I have a listview. What I've implemented in that listview is that when user clicks a list item a 2 button view is inflated to replace the content of that list item like this:
This works fine but what I want is when I click the second list item the first one should come back to its original layout. Currently, it is like this:
This is my code implemented in onClick method of listview:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView planName = view.findViewById(R.id.planNameText);
TextView planDate = view.findViewById(R.id.planDateText);
ImageView planImage = view.findViewById(R.id.homePlanImageView);
planName.setVisibility(View.INVISIBLE);
planDate.setVisibility(View.INVISIBLE);
planImage.setVisibility(View.INVISIBLE);
RelativeLayout rl_inflate = (RelativeLayout)view.findViewById(R.id.rl_inflate);
View child = getLayoutInflater().inflate(R.layout.inflate, null);
rl_inflate.addView(child);
}
});
Thanks.
Maybe you need to initialice a boolean variable to check if is clicked or not and refresh all the views. I really recommend you to use a RecyclerView and use 2 viewHolders. If you want information about this check this. If you implement a recycler with 2 viewholder it will be easier than the way that you want to implement it, and you can use notifyDataSetChanged to refresh the recycler. Whatever, you will need anyways a boolean to check if is clicked or not.
Related
I have a GridView adapter displaying a grid of Buttons. Now I want to set up an OnClickListener for my buttons but of course they don't have their own R.id I can access as they are added to the grid via the adapter, rather than a layout.xml.
I tried to use OnItemClickListener as follows:
m_onItemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int pos, long l) {
switch(pos) {
case MyConstants.POS_OF_BUTTON_1:
// Do stuff...
break;
case MyConstants.POS_OF_BUTTON_2:
// Do stuff...
break;
}
}
};
But to my understanding you can't use a clickable or focusable item with OnItemClickListener. How do I get round this? Thanks!
There are more elegant ways to do this whole thing (starting from using a RecyclerView with a GridLayoutManager instead of a GridView), but if you're looking for the quick and easy solution to use with what you already have, this is what you can do:
First of all, you should set some ID on your buttons, they don't have to come from R.id (although it would be preferable if you inflated the views from a layout, with an ID defined there, and used a ViewHolder).
Worst case, you can just define constants in your adapter for the IDs you want to use for each kind of button (e.g. static final int DELETE_BUTTON = 1;), and then set these IDs on the buttons manually, in code.
Then you can pass a simple OnClickListener (not OnItemClickListener), which handles clicks of all these different buttons in a single item, to your adapter, and make the adapter set the listener on each of these buttons, for each of the item views in the grid.
You will also need to set the position of the item as a tag on the button view itself, so that when the click happens, you can determine for which item the click happened.
Sample code as follows:
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Object tag = v.getTag();
if (!(tag instanceof Integer)) {
// Show error message or just throw an exception.
}
int position = (Integer) tag;
// We get the item at this position, to know which one to use
Item item = adapter.getItem(position);
switch (v.getId()) {
case DELETE_BUTTON:
// Delete stuff here
break;
case EDIT_BUTTON:
// Edit stuff here
break;
...
}
}
};
adapter.setOnClickListener(listener);
Then, in the getView method of the adapter, you need to set this listener on each of the buttons and also set the position of the item as a tag on the buttons. This way, you will be able to figure out to which item the button belongs to, in the listener code above.
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
...
deleteButton.setId(DELETE_BUTTON);
deleteButton.setOnClickListener(listener);
deleteButton.setTag(i);
...
}
In general, I sincerely urge you to also look into the ViewHolder pattern, and RecyclerView and GridLayoutManager when you have time. Most of this will translate there as well.
EDIT
In order to make multiple Views clickable/focusable inside a list/grid item, you need to set the descendantFocusability attribute to blocksDescendants on the root view of the item, either simply in the XML, or in code via:
viewGroup.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
I have a listview with items from the adapter. And when I try and retrieve new information, I'm putting a RelativeLayout with loading images and stuff on top of it.
The problem is, is that my listview and adapter items are still clickable. They can only be clickable after the loading is done. When the loading is done I am triggering (notification) a setVisibility(View.gone) on that LoadingLayout.
I tried:
listview.setFocusable(false);
listview.setClickable(false);
listview.setEnabled(false);
But it is not working
I guess the:
row.setOnClickListener(this);
in the getview method of the adapter is still on?
How do I make it not clickable? Do I get a list of views or something and make them unclickable, but then again. Only the views that are onscreen should be not clickable for that moment? Or is there some other clever method? (I thought the overlaying relativelayout would be clever ... guess not)
Declare a variable in class where you are calling setAdapter to list view as follows
OnItemClickListener myAdapterItemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position,
long id) {
// TODO your row onclick actions
}
};
Before loading all the stuff, you can set
listview.setOnItemClickListener(null);
After loading it,
listview.setOnItemClickListener(myAdapterItemClickListener);
I have a list view that uses different layout sheets for different rows. Each sheet has different variables on them. So, when I want to implement the click listener for my list I need to know which type of row I am clicking on so that I can try to access to the correct values. For example:
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//do this for layout A
//......
// do that for layout B
//......
}
});
How can I access to the layout information and the corresponding values ?
Make sure that you have a variable in your activity where you've kept the data with which you've populated the adapter.
Then, based on the position variable, you'll be able to get the exact row which was clicked. Then based on the row, you'll be able to figure out what type of row it is, right? :)
you can use the method:
public abstract int getItemViewType (int position) of your custom adapter.
I have a ListView with a CheckBox.
What I am trying to implement is an onItemClick (in my activity) that check/select my CheckBox if I click on the row, as you can see below:
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
MyItem row = ListofRows.get(position);
row.setSelected(true);
myAdapter.notifyDataSetChanged();
}
When I click in the row, the ListView is refreshed because of the method notifyDataSetChanged()
THE PROBLEM IS: this method refreshes the whole ListView and as a result, the ScroolBar goes to the beginning (the user is driven to the header of the list) even if the user is at the bottom of the list.
WHAT I NEED IS: Refresh just this single clicked row so the user won't be driven to the beginning of the list.
Are there any solutions to this problem?
use the selected index
View v = getListView.getChildAt(index);
Now update the view with the new values.
I have a custom listview. I have to select some items from this listview and display it in the next layout listview when a button click event is clicked.
lv5=(ListView)findViewById(R.id.ListView05);
lv5.setAdapter(new ArrayAdapter<String>(this,R.layout.productselecttext,R.id.pstext,arr));
lv5.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(view.findViewById(R.id.oi).getVisibility()==ImageView.VISIBLE){
ImageView icon = (ImageView)view.findViewById(R.id.oi);
icon.setImageResource(R.drawable.vi);
}
}
});
In this way I have selected using an imageview. How can I get only the selected items and display in another listview?
It all depends on what you call a selected item. We need some more code to understand how you "selected" items in the first listview.
But generally speaking, all you have to do is to build a new Adapter for the second list view that just lists the selected item. You could even recylcle the first adapter and the first view, just eliminating the items that are not selected from the adapter's list and calling
notifyDatasetChanged()
on your first adapter to update your first list.
Regards,
stéphane