Hi I have a tableLayout and am populating the layout with ImageView[][] using a nested for loop. I'm currently trying to click on an ImageView and rearrange the ImageView[][] data then refresh the screen to reflect the rearrangement. Is there a way to do this? Apparently I can't call the setContentView more than once.
Edit: you can see this is the code for the onclick event. I setContentView of the original TableLayout ('tl') in the onCreate event and can't call it again here.
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case 1:
image_array = switchTile(image_array, 2,1,0,0);
Toast.makeText(this, "1 clicked!", Toast.LENGTH_LONG).show();
}
tl.removeAllViewsInLayout();
for(int i = 0; i < level; i++){
TableRow new_tr = new TableRow(this);
new_tr.setLayoutParams(layout_image);
for(int j = 0; j< level; j++){
new_tr.addView(image_array[i][j]);
}
tl.addView(new_tr);
}
tl.invalidate();
}
try this: tableindex.removeAllViews();
If all you want to do is move the images around, you can just do setImageBitmap () operations on the existing ImageViews. You can use the same bitmaps and display them on whichever ImageViews you please.
Related
I created array of buttons in a loop. It seems to work, but if I add OnClickListener to each button, I get a NullPointerException. How do I fix that?
This is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
fieldModel=new Field();
buttons=new Button[10][10];
for(int i=0; i<10; i++) {
for (int j = 0; j < 10; j++) {
String buttonID = "button" + i + j;
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[i][j] = ((Button) findViewById(resID));
buttons[i][j].setOnClickListener(new View.OnClickListener() { // <-- I get the exception here...
#Override
public void onClick(View v) {
"some action"
}
});
In R.layout.main_layout, are there 100 buttons named 'button00' to 'button99'? if any one is missing, it will result in a null pointer at the line you have marked.
It would also be worth looking at using a GridView, or a RecyclerView with GridLayoutManager, instead of adding the buttons manually - if it would suit your app.
You get the exception because the id isn't contained by the activity layout. You have to add them first in the layout file if you want to match the Button object through findViewById or, if you have them already, make sure the Id you use in findViewById (resId) is correct.
I dynamically create Buttons by entering a word. If I write "met", it appears on the screen - one Button per letter. The same thing happens for the next word I enter, and it appears below the previous word --- as shown in the image above.
When I click on a Button it turns green. My question is, what is the best way to disable the clicking of a row of Buttons. Meaning, if the user clicks on the 'm' in "met" I want the user to only be able to click on the Buttons in "met" and to not be able to click on any of the Buttons in "had", "goes", or "ran"
Here is my code:
EDIT
int size = enter_txt.getText().toString().length();
for (int i=0; i<size; i++){
final Button dynamicButtons = new Button(view.getContext());
dynamicButtons.setLayoutParams(rlp);
dynamicButtons.getLayoutParams().width = 130;
dynamicButtons.getLayoutParams().height = 130;
dynamicButtons.setTag("0");
dynamicButtons.setId(1);
dynamicButtons.setText(edit_text_array[i]);
dynamicButtons.setBackgroundResource(R.drawable.button);
button_list.add(dynamicButtons);
linearLayout2.addView(dynamicButtons, rlp);
dynamicButtons.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
int i=0;
LinearLayout ll = (LinearLayout) dynamicButtons.getParent();
for(i=0; i<list_of_ll.size();i++){
if (ll == list_of_ll.get(i)){
list_of_ll.get(i).setId(i);
break;
}
}
if(list_of_ll.get(i).getId()==i)
ButtonOnClick(view);
}
});
}
linearLayout2.setId(0);
linearLayout2.setTag("0");
list_of_ll.add(linearLayout2);
EDIT
I created a List of the LinearLayouts for each row of Buttons. The Buttons turn green if the id of the LinearLayout is set to 1. When I click on a Button I want that LinearLayout to stay at 1 and have all other rows/LinearLayouts set to 0 so they become unclickable.
Currently, every Button I click turns green even if it's in a different row. Can someone please help me solve this issue?
Why you don't set Id in the for loop so that you are able to refer and set the onlicklistener to null like jpcrow already mentioned.
Set Id like:
YourCreatedBtn.setId(i+1);
//Id's setted programmatically don't.
have to be unique... But they should be
a positive number (referring to the
android documentation)
And in your on click method simply set onclicklistener for specified Id's to null. Just a hint, hope it helps
Update regarding Thread-openers Comment
I found two simple ways but i would prefer the one which is not commented out in the buttonIsClicked:
LinearLayout llrow;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
llrow = (LinearLayout) findViewById(R.id.test_layout);
//Adding 5 Buttons
for(int i = 0; i<5; i++) {
Button mybtn = new Button(this);
//set LayoutParams here
mybtn.setId(5);
mybtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
buttonIsClicked(v);
}
});
llrow.addView(mybtn);
}
}
private void buttonIsClicked(View v) {
/*ArrayList<View> myButtons = llrow.getTouchables();
for(int i = 0; i < llrow.getChildCount(); i++){
myButtons.get(i).setOnClickListener(null);
}*/
for(int i = 0; i<llrow.getChildCount(); i++){
llrow.getChildAt(i).setOnClickListener(null);
}
}
It's just a simplified Version of your code, but i'm sure you will get the Content..
What if found out is, that you don't have to set the ID in both cases.. You can easily get all the child over
YourRowLinearLayout.getChildAt(starting from 0 to n-1-Views you added)...
I didn't found a way around the for-loop... But this small-little loop will not break your neck regarding to Performance..
The outcommented-code is the second Approach, finding all the Child over getTouchables which logically leads to an ArrayList and that's exactly the reason why i don't like it. You have to initialize an arraylist...... However, this also won't break your neck regarding to Performance but a penny saved is a penny got! ;) Hope it helps and everything is clear. Both of them work! Please mark as accepted answere if it fits your Needs...
You have to distinguish between the two rows, either add them to different ViewGroups or you can use View.setTag(int key, Object tag)
I was looking through some topics but couldn't find exact answer or at least couldn't get it right. What happens in the code is that i create one button for each row in my database and each button is supposed to have an OnClick that sends us to another activity along with some values(each button is supposed to have different value) but in the end it seems like i get the same value for all of my buttons which makes me think that it only creates 1 view for all of the buttons.
Cursor przepis = bazaUzytkownikow.rawQuery("SELECT * FROM przepisy", null);
int liczba_wierszy = przepis.getCount();
przepis.moveToPosition(0);
for (int i = 0; i < (liczba_wierszy/4)+1; i++) {
LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
for (int j = 0; j < 4; j++) {
if((przepis.moveToPosition((i*4)+j)!=false))
{
nrPrzepisu=(i*4)+j;
Button btnTag = new Button(this);
btnTag.setLayoutParams(new LayoutParams(115, 60));
btnTag.setText(przepis.getString(przepis.getColumnIndex("nazwa")));
btnTag.setTextSize(10);
btnTag.setId(j + 1 + (i * 4));
btnTag.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View t) {
// TODO Auto-generated method stub
Intent IdzPrzepis = new Intent(getApplicationContext(), DodajPrzepis.class);
IdzPrzepis.putExtra("ID_uzytkownika", ID_uzytkownika);
IdzPrzepis.putExtra("nr_Przepisu", nrPrzepisu);
startActivity(IdzPrzepis);
}
});
row.addView(btnTag);
}
}
layout.addView(row);
}
To make the code more clear for you - bazaUzytkownikow is my database, liczba_wierszy is the number of the rows that i got. I move the cursor to the beginning since it's where i want to start and i proceed to "cut" my data using 2 loops. I am aiming for 4 buttons in 1 row.
The part that i think doesn't work is the OnClick method where i want my button to switch activity and send nrPrzepisu which is basically adding a connection between my button and proper row in the database (In the other activity i want to set text, reading rows from database depends on which button you click).
I checked the other activity and it seems to be reading same nrPrzepisu everytime which usually equals the last value of nrPrzepisu=(i*4)+j when loops finish and it made me think that i somehow need to make different views for each button.
you are passing the same object to each onClick then changing that object with the next iteration. In the end all the onClicks have the same nrPzepisu object and it is returning the value which is whatever is last in this example.
int nrPrzepisu = (i*4) + j;
This way you aren't passing the same object into all the onClicks.
the problem is that my layout is to type on and I need a TextView move from one party to an 'other screen, to do this I make sure that the layout view and then remove all face appear again the same TextView in such a way as not to have that the TextView be "dragged" across the screen.
Here's my code:
Textview textview = new TextView(context); //context was been defined
poiView.removeAllViews();
for (int j = 0; j < poiP.length; j++) {
//code
texview.setText("iojforj");
poiView.addView(textview, params); //params was been defined
textview.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
function (v.getId());
}
});
Now the problem is that the TextView seems, it works, moves and so on but will not let me access the method Mr clicks because the TextView is removed and put in the time.
Instead of removing and re-adding the textView, you should just mess with it's visibility.
So instead of removing them and adding them later on, you should just do
textView.setVisibility(View.INVISIBLE); //to make it disappear
textView.setVisibility(View.VISIBLE); //to make it reappear
that way they will keep their assigned OnClickListeners
however if this is running from a different thread, you need to put this in a runOnUiThread() call.
EDIT:
lets try this
Textview textview = new TextView(context); //context has been defined
poiView.removeAllViews();
OnClickListener buttonListener = new OnClickListener() { //listener here }
for (int j = 0; j < poiP.length; j++)
{
//code
texview.setText("iojforj");
poiView.addView(textview, params); //params was been defined
textview.setOnClickListener(buttonListener);
}
I'm trying to make my life a heck of a lot easier by cycling through buttons in my xml (because I have a ton of buttons). Why isn't this working?
Button bf[];
public static final int[] Buttons = { R.id.b1, R.id.b2, R.id.b3, R.id.b4,
R.id.b5, R.id.b6, R.id.b7, R.id.b8, R.id.b9, R.id.bBack,
R.id.bClearAll, R.id.bClear };
I have a static final int that holds some of my buttons, which is list in the header.
Within my onCreate method I set up my buttons:
for (int i = 1; i < 10; i++) {
bf[i] = (Button) findViewById(Buttons[i - 1]);
bf[i].setOnClickListener(this);
}
Nice and easy right? but then when I try to reference them in the switch and case (within my implemented onClickListener method, I'm having problems:
for (int i = 1; i < 10; i++) {
case Buttons[i-1]:
Toast.makeText(this, bf[i].getText(), Toast.LENGTH_SHORT).show();
break;
}
This doesn't work, so then I just tried a single reference:
switch (v.getId()) {
case Buttons[0]:
Toast.makeText(this, bf[1].getText(), Toast.LENGTH_SHORT).show();
break;
which doesn't work either?!?! Help please?
v is your View in the onClickListener, right?
Why don't you use:
Button b = (Button) v;
Toast.makeText(this, b.getText(), Toast.LENGTH_SHORT).show();
Some other points:
You did not post the complete code but I guess you can change your Buttons array to private.
Probably you don't even need bf[]
Edit: Also I'd suggest to use this for-loop to cycle through all of your buttons to make it more flexible:
for (int i : Buttons) {
Button b = findViewById(i);
b.setOnClickListener(myClickListener);
}