I've tried to follow the several other times this question has been asked but all other reports of what's working seem to be the same as mine, except mine doesn't work. It compiles and runs and doesn't crash, but it simply does not do what it's supposed to do. In the code, the "Alpha" error log DOES NOT occur, so it is not recognizing that it's clicked.
Here's the relevant snippet of code. Any ideas?
for(int i=0; i<[big long statement]; ++i)
{
final TextView resourceText= new TextView(ctx);
resourceText.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
resourceText.setText([big long statement]);
resourceText.setTextSize(18);
resourceText.setClickable(true);
resourceText.setFocusable(false);
resourceText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("Alpha", "Alpha");
resourceText.setTextColor(Color.RED);
}
});
scrollLinearLayout.addView(resourceText);
}
This is where scrollLinearLayout is created
//Add Linear Layout for the scrollview
scrollLinearLayout = new LinearLayout(ctx);
scrollLinearLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));
scrollLinearLayout.setOrientation(LinearLayout.VERTICAL);
//scrollLinearLayout.setId(MyR.Ids.ROOMDIALOGFRAGMENTLL_ID);
resourceScrollView.addView(scrollLinearLayout);
Thanks
Maybe you should move the listener away from loop :
for(int i=0; i<[big long statement]; ++i)
{
final TextView resourceText= new TextView(ctx);
resourceText.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
resourceText.setText([big long statement]);
resourceText.setTextSize(18);
resourceText.setClickable(true);
resourceText.setFocusable(false);
resourceText.setOnClickListener(onClickListener);
scrollLinearLayout.addView(resourceText);
}
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("Alpha", "Alpha");
((Button)v).setTextColor(Color.RED);
}
};
it is because your linearlayout encompasses the textview, resourceText. If you allow the LinearLayout to consume the clicks, then the textview will never see a click. You need to Try adding android:descendantFocusability="afterDescendents" to the LinearLayout
Related
I have a LinearLayout ("ll") that is already created in xml and the app dynamically creates another LinearLayout inside of it and creates an EditText and a Button inside of that view. The button makes the whole LinearLayout destroy itself along with the EditText and Button inside it (the whole system is a player name entering activity). Anyway, I am trying to find a way to get the text from all of the EditTexts. I have tried using a for loop on "ll" and using ll.getChildAt() but I can't seem to use .getChildAt() on whatever ll.getChildAt() generates because getChildAt() generates a "View" not a "LinearLayout." I basically just need a way to search two children in, rather than just one. Also, if there is just a better way I should be doing this, let me know. I'm open to suggestions.
Here's my code if it will help:
NewGameCreate.java
public class NewGameCreate extends Activity {
int numOfPlayers = 0;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_game_create);
}
public void newPlayer(View view) {
numOfPlayers++;
final LinearLayout ll = findViewById(R.id.playerView);
final LinearLayout llNew = new LinearLayout(getApplicationContext());
llNew.setOrientation(LinearLayout.HORIZONTAL);
llNew.setId(numOfPlayers);
ll.addView(llNew);
EditText newName = new EditText(this);
newName.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1));
newName.setHint("Enter Player Name");
newName.setId(numOfPlayers);
newName.setWidth(0);
llNew.addView(newName);
final Button delete = new Button(this);
delete.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0));
delete.setText("Delete");
delete.setId(numOfPlayers);
delete.setWidth(0);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = delete.getId();
ll.removeViewInLayout(findViewById(id));
Drawable back = ll.getBackground();
ll.setBackgroundColor(00000000);
ll.setBackground(back);
ll.invalidate();
}
});
llNew.addView(delete);
}
public void startGame(View view){
LinearLayout ll = findViewById(R.id.playerView);
List text = new ArrayList();
for(int loop = 0; loop < ll.getChildCount(); loop++) {
//this is the code in question and where I want to get the text from
//all my EditTexts
LinearLayout inner = ll.getChildAt(loop);
}
}
}
I think I found the answer to it. You need to change a little bit of code in the startGame() method I m providing the code for startGame below.
public void startGame(View view) {
LinearLayout ll = findViewById(R.id.playerView);
List text = new ArrayList();
for (int loop = 0; loop < ll.getChildCount(); loop++) {
//this is the code in question and where I want to get the text from
//all my EditTexts
LinearLayout inner = (LinearLayout) ll.getChildAt(loop);
for (int j = 0; j < inner.getChildCount(); j++) {
if (inner.getChildAt(j) instanceof EditText) {
EditText textET = (EditText) inner.getChildAt(j);
Log.d("TAG",textET.getText().toString());
}
}
}
}
In the above code you were able to get the first child only but as you have added a linearLayout with orientation Horizontal in a parent LinearLayout with orientation Vertical, you have written code for the child of parent layout i.e playerView. I have modified the code to get the elements of the child Linear layout and Log prints all the text from the EditText.
Hope that helps!!
Background
I am creating buttons dynamically in a for loop by following Pragnesh Ghota's solution of one onClick listener for every button in the format of dymmeh's individual initialization solution:
LinearLayout someLayout = (LinearLayout) findViewById(R.id.theRoom);
for (int i = 0; i < neededButtons.length; i++){
neededButtons[i] = new Button(this);
neededButtons[i].setText(names[i]);
neededButtons[i].setOnClickListener(this);
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
}
In addition, I am making one onClick listener by implementing View.OnClickListener in the actvity class. My class is defined as such:
public class RecallActivity extends AppCompatActivity implements View.OnClickListener{
...
}
I have followed the other steps of Pragnesh Ghota's solution with success. However...
Problem
The fourth step of Pragnesh Ghota's solution mentions the use of a case statement to check if any of the buttons have been clicked. This works when the amount of buttons is known. However, since I am following the format laid out in dymmeh's solution, I do not know how many buttons I am checking until execution time.
Question
How do I do a control flow statement within an overrided onClickMethod for a dynamic amount of buttons?
Just create a new OnClickListener for each button when you're creating them.
LinearLayout someLayout = (LinearLayout) findViewById(R.id.theRoom);
for (int i = 0; i < neededButtons.length; i++){
neededButtons[i] = new Button(this);
neededButtons[i].setText(names[i]);
neededButtons[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// add your click listener code here
}
})
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
}
you can set a id for button .just like this:
LinearLayout someLayout = (LinearLayout) findViewById(R.id.theRoom);
for (int i = 0; i < neededButtons.length; i++){
neededButtons[i] = new Button(this);
neededButtons[i].setText(names[i]);
neededButtons[i].setId(i);
neededButtons[i].setOnClickListener(this);
...
);
}
then find view by id in OnClickListener. for example:
public class RecallActivity extends AppCompatActivity implements View.OnClickListener{
#overide
public void onClick(View view){
if(view.getId == 0){
.....
}
}
}
The simplest solution is using setTag and getTag for your buttons. You can use an object with setTag and getTag. Whenever you're creating a button, set the tag for it:
for (int i = 0; i < neededButtons.length; i++){
neededButtons[i] = new Button(this);
neededButtons[i].setText(names[i]);
neededButtons[i].setTag(names[i]);
// or you can use the index as the tag with:
// neededButtons[i].setTag(i);
neededButtons[i].setOnClickListener(this);
}
Then you do something for each button by checking the tag:
#Override
public void onClick(View v) {
doSomething(v.getTag());
}
private void doSomething(Object tag) {
// in case your tag is the index, than you can convert it to
// integer and use switch case
int index = (int) tag;
switch(index) {
case 1:
...
break;
case 2:
...
break;
...
}
}
I have a Linearlayout called "resultView". I then dynamically added many textViews in it after clicking a button.
I want to remove all the textviews that I just created when I click the button again.
btn_search.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View view) {
resultView.removeAllViews();
String strFileName = et_fileName.getText().toString();
searchFiles(strFileName);
}
});
public void searchFiles(String strFileName){
....
for (int i = 0; i < fileList.size(); i++) {
TextView textView = new TextView(this);
textView.setText(fileList.get(i).getName());
textView.setPadding(5, 5, 5, 5);
if (fileList.get(i).isFile())
resultView.addView(textView);
}
}
App Screenshot, All the listed results are dynamically created textViews.
My XML, the id "view" is my resultView.
But resultView.removeAllViews(); doesn't work. The results are still appened.
Calling resultView.invalidate(); after that doesn't work either.
What should I do to make the layout refresh?
Use .invalidate() to upddate UI.
I have successfully added a TableRow to the TableLayout,now I would like to programmatically remove the TableRow and add the original row to the TableLayout.Here is the code that I use to generate the TableRow:
public TableRow getTableRow(String text,String hint,boolean addCollapseOption)
{
TableRow tr=new TableRow(getBaseContext());
tr.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT,TableRow.LayoutParams.WRAP_CONTENT));
TextView temp=new TextView(getBaseContext());
temp.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,TableRow.LayoutParams.WRAP_CONTENT));
temp.setText(text);
tr.addView(temp);
tempId="edit_"+count;
count++;
EditText edit_temp=new EditText(getBaseContext());
TableRow.LayoutParams edit_params=new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,TableRow.LayoutParams.WRAP_CONTENT,1f);
edit_params.setMargins(10, 0, 10, 0);
edit_temp.setLayoutParams(edit_params);
edit_temp.setHint(hint);
tr.addView(edit_temp);
if(addCollapseOption)
{
ImageButton btn_less=new ImageButton(getBaseContext());
btn_less.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,TableRow.LayoutParams.WRAP_CONTENT));
btn_less.setImageDrawable(getResources().getDrawable(R.drawable.icon_less));
btn_less.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v)
{
shouldCollapse=true;
}
});
tr.addView(btn_less);
}
return tr;
}
The Activity crashes when I try to add this TableRow to the TableLayout:
TableRow tr=getTableRow("First Name","Enter first name here",true);
I guess you cannot remove a View from the Layout and still be able to use the click event in it(that crashes the activity),layout and shouldCollapse are global variables,if set to true:
if(shouldCollapse)
{
layout.removeAllViews();
layout.addView(originalRow);
}
EDIT:Changing the implementation to use removeChildAt does not work:
if(shouldCollapse)
{
int childCount=layout.getChildCount();
for(int i=1;i<childCount;i++)
layout.removeViewAt(i);
originalRow.setVisibility(TableRow.VISIBLE);
shouldCollapse=false;
}
Now,clicking on the btn_less does absolutely nothing.This is the Logcat's opinion of the problem:
Less clicked
The value of shouldCollapse true
So,this means that even though shouldCollapse is set to true but this method is never called...strange.
You can use this code to remove the programmatically generated TableRows:
public void onClick(View v)
{
final TableRow parent = (TableRow) v.getParent();
tr.removeView(parent);
}
Or if you want to use this out side the onClick, you must pass the value of View v to whatever function it is.
HI,
I want to create a table in android, should contains a lot of rows. Each row has 4 columns, and if i click any view, i want to integrate onClick event for the view.
I have developed something similar to the requirement,But didn't got the click view, Here is my code :
LinearLayout lLayout1= null;
LinearLayout main_lLayout= null;
LinearLayout lLayout2= null;
TextView myText[] = new TextView[12];
LinearLayout myLayout[] = new LinearLayout[12];
#Override
public void onCreate(Bundle icici) {
super.onCreate(icici);
main_lLayout = new LinearLayout(this);
main_lLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
main_lLayout.setOrientation(LinearLayout.VERTICAL);
int k = 0;
for(int i=0;i<4;i++) {
myLayout[i] = new LinearLayout(this);
for(int j=0;j<4;j++) {
myText[j] = new TextView(this);
myText[j].setText("asdf"+i+j);
myText[j].setPadding(0, 0, 20, 10);
myText[j].setClickable(true);
myText[j].setId(k);
myText[j].setOnClickListener(this);
k++;
System.out.println(k);
myLayout[i].addView(myText[j]);
}
main_lLayout.addView(myLayout[i]);
}
setContentView(main_lLayout);
}
#Override
public void onClick(View v) {
System.out.println(myText[0].getText());
System.out.println(myText[10].getText());
}
You have some bad array management there... you're instantiating 16 TextViews but only assign them to the first 4 elements of myText. If you fix this I find the click handler is called as expected.