I am new to Android development and I am trying to handle clicks on a grid of items. What is the best way to do that? So far I have something like this to set the onclicklistener:
TableLayout layout = (TableLayout) findViewById(R.id.tableLayout1);
for (int i = 0; i < layout.getChildCount(); i++) {
View v = layout.getChildAt(i);
if (v instanceof TableRow) {
for (int j = 0; j < ((TableRow)v).getChildCount(); j++) {
View v2 = ((TableRow)v).getChildAt(j);
v2.setOnClickListener(this);
}
}
}
Now I want to handle the clicks on the items contained in the table. As there are many items I want to avoid writing a long "switch". The items have logical IDs containing the number of the row and the column. Is there a way to get the actual ID of the item that has been clicked (the ID in the XML) and then parse it? If not, what would be the solution.
Thanks
You have a few options. You can set the onClickListener inline:
v2.setOnClickListener(new OnClickListener() {
public void onClick (View viewClicked) {
Log.d("View row: " + i + ", column: " + j);
// or something else
}
});
Or you can use the View.setTag(), which will allow you to store key-value pairs to the view, similar to a map.
Related
I have several elements that i want to set with the same property. Is it possible with a for loop? Thanks in advance. This is what I have so far:
public void invisible(){
int[] buttons = {R.id.key1, R.id.key2, R.id.key3, R.id.key4, R.id.key5, R.id.key6, R.id.key7
, R.id.key8, R.id.key9, R.id.key10, R.id.learn,R.id.kit1,R.id.kit2};
for(int i=0; i<buttons.length; i++){
//set invisible?
}
}
for (int i = 0; i < buttons.length; i++) {
findViewById(buttons[i]).setVisibility(View.INVISIBLE);
}
This should work. You iterate over the view ids, search for the view in your layout hierachy and set the visibility.
I have many controls in an activity layout in Android, and
i want to get their value in a simple for, the problem is that
Eclipse assigns the ID randomy, so I cannot get controls ID in a
sequential way to access the controls in a for loop because
they are not sequential IDs.
Here is why I am trying to do:
int visibleId = R.id.fieldVisible1;
int editId = R.id.editField2;
int spinnerId = R.id.spinner1;
for(int nIndex = 0; nIndex < 12; nIndex++)
{
CheckBox checkBox = (CheckBox)findViewById(visibleId + nIndex);
checkBox.setChecked(_fieldsInfoArray.get(nIndex).getVisible() == 1);
EditText edit = (EditText)findViewById(editId );
edit.setText(_fieldsInfoArray.get(nIndex).getName());
Spinner spinner = (Spinner)findViewById(spinnerId + nIndex);
spinner.setSelection(_fieldsInfoArray.get(nIndex).getOffset());
}
how can I make Eclipse to assign sequential IDs to controls so I can
just increment by 1 the id in a loop?
A better way of doing this may possibly to look into the use of:
int children = layout.getChildCount();
for (int i=0; i < children; i++){
View v = ll.getChildAt(i);
}
This would allow you to loop over all views inside the layout without needing to know their IDs.
I am using a multi select listview in my application. Specifically the simple_list_item_activated_1.
I have some of code, a button, that will select all the listview items. I have some logic saying that if all the items are already selected then deselect all the items.
When I press the button the first time, it will select all the items in the list as expected. and when I press the button a second time it deselects all the items as expected.
Here is my problem:
When I press the button for a third time "selectedCount" still equals "childCount". So obviously my code will never enter the If statement.
Would anyone know why this is happening? or maybe there is a better way to do what im trying to achieve?
int childCount = officerList.getChildCount();
int selectedCount = officerList.getCheckedItemPositions().size();
if(childCount != selectedCount){
for (int i = 0; i < officerList.getChildCount(); i++) {
officerList.setItemChecked(i, true);
}
}else{
for (int i = 0; i < officerList.getChildCount(); i++) {
officerList.setItemChecked(i, false);
}
}
}
Try this logic, it will check all the items if none of the items are checked, else will check only the items which are unchecked and vice versa.
public void onClick(View v) {
SparseBooleanArray sparseBooleanArray = officerList.getCheckedItemPositions();
if(sparseBooleanArray != null && sparseBooleanArray.size() >0) {
for (int index = 0; index < sparseBooleanArray.size(); index++) {
if(sparseBooleanArray.valueAt(index)){
officerList.setItemChecked(sparseBooleanArray.keyAt(index),true);
}
else {
officerList.setItemChecked(sparseBooleanArray.keyAt(index),false);
}
}
}
else {
for (int index = 0; index < officerList.getCount(); index++) {
officerList.setItemChecked(index,true);
}
}
}
I managed to answer my own question. Using getCheckItemPositions().size() is an unreliable way of achieving what I want.
This will return a sparseBooleanArray() of all Items checked, so the first time it works correctly as initially there is nothing selected so it will return 0. Then once everything is selected the sparseBooleanArray will be equal to all the items in the list as they were all selected.
However as I learned spareBooleanArray is an Array that stores the position and a Boolean flag of if it is selected or not. In my scenario when I press the select all button for the third, the size of the array is still equal to number of list items.
How I have fixed my issue, is to use getCheckedItemCount() which only returns the number of selected items as I originally wanted. hopefully this answer will help someone else.
int childCount = officerList.getChildCount();
int selectedCount = officerList.getCheckedItemCount();
if(childCount != selectedCount){
for (int i = 0; i < officerList.getChildCount(); i++) {
officerList.setItemChecked(i, true);
}
}else{
for (int i = 0; i < officerList.getChildCount(); i++) {
officerList.setItemChecked(i, false);
}
}
}
I am trying to create dynamic buttons. When clicking a button it should go to the specified url assigned to the text of the button.
For testing, first I tried to get that ID, if it is equal it prints the value of i. But whenever I clicked any one button, instead of telling that particular i value, it enters into whole loop, and prints all the values of i starting from 1 to 19 (the number of buttons that are dynamically created)
And after printing all values from 1 to 19, the program is getting force closed saying Null pointer exception.
I even tried by placing the handler code outside onCreate(), but I'm still getting the same error.
for ( i = 0; i <itemList.getTitle().size()-1; i++) {
title[i] = new TextView(this);
title[i].setTextColor( -16711936 );
title[i].setTextSize(18);
title[i].setText("Title = "+itemList.getTitle().get(i));
description[i] = new TextView(this);
description[i].setTextColor(-16776961);
description[i].setText("Description = "+itemList.getDescription().get(i)+"......");
more[i]=new Button(this);
more[i].setText(itemList.getLink().get(i));
layout.addView(title[i]);
System.out.println("Title view is set");
layout.addView(description[i]);
//System.out.println("Description view is set");
layout.addView(more[i]);
more[i].setOnClickListener(listener);
}
private OnClickListener listener=new OnClickListener(){
public void onClick(View arg) {
int index = 0;
for (i = 0; i < more.length; i++)
{
if (more[i].getId() == arg.getId())
{
index = i;
System.out.println("Value of i onclick is"+i);
}
}
//System.out.println("Vlaue of I in onclick"+i);
//Uri uri=Uri.parse(itemList.getLink().get(i));
//startActivity(new Intent(Intent.ACTION_VIEW,uri));
//Toast.makeText(getApplicationContext(), "This button is clicked"+i+more[i].getText()+itemList.getLink().get(i),Toast.LENGTH_LONG).show();
}
}
You can use setTag() and getTag() method of View to identify different button.
for (i = 0; i < itemList.getTitle().size()-1; i++) {
...
more[i].setTag(i); // Use index of itemList as the tag
}
In onClick:
int index = (Integer)arg.getTag();
you can also set the id of button
more[i].setid(i);
int index = 0;
for (i = 0; i < more.length; i++)
{
if (more[i].getId() == arg.getId())
{
index = i;
System.out.println("Value of i onclick is"+i);
}
}
As you can see here, i is still in your for loop.
Put the System.out.println("Value of i onclick is"+i); outside of your for loop and it should work
PS: format your code, it's easier to read that way and you'll notice small mistakes like these more easily
I think this will help you..
set button tag also dynamic like
more[i].setId(i);
and also changed condition like
if (more[i].getId() == i) {
index = i;
}
hope this will help you...
I am stuck with an issue in my project.The need is to show all data fetched from server using webservices.I successfully get data from server using json.but i want to show data on screen in tabular format 50 records at a time.Please suggest me how to do this or if you can guide me through a better way to implement paging in android.
The code of paging is here :
Implement Pagination on tab layout
and the function i use to append rows dynamically to tablelayout is :
private void appendRows(TableLayout table, String[] data) {
int rowSize = data.length;
int colSize = (data.length > 0) ? 1 : 0;
for (int i = 0; i < rowSize; i++) {
TableRow row = new TableRow(this);
for (int j = 0; j < colSize; j++) {
String[] rowVal = null;
rowVal = data[i].split(",");
for (int k = 0; k <= rowVal.length - 1; k++) {
TextView c = new TextView(this);
c.setText(rowVal[k]);
c.setTextColor(getResources().getColor(R.color.white));
c.setPadding(3, 3, 3, 3);
row.addView(c);
}
}
table.addView(row, new TableLayout.LayoutParams());
}
}
Please guide me I need to show hyperlink page numbers at the bottom of my window as shown in google
This might be of some help. Its a tutorial for pagination. Here is the source code.
I have had similar requirement like yours and I normally use the listview for it. Due to the recycling of views it is a lot more efficient than using a table layout.
You can create a custom adapter where you always return the size as 50+1, 100+1. So in your onItemClickListener you can check if the row position is more than the items, if so, then you add the next 50 items to the adapter. This is a basic idea of how to do it.