How to set the visibilty of button in a custom Lis

2019-09-06 13:38发布

问题:

I have a custom ListView with a button, so when I click on a button it should disappear and it is disappearing but when I scroll down and come back the button is again appearing and a different button is getting disappeared. How can i make the specific button to disappear on clicking.... I am using this code

holder.checkbox = (Button) view.findViewById(R.id.checkBox1);

holder.checkbox.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
    holder.checkbox.setVisibility(View.INVISIBLE);

回答1:

In ListView when an item goes out of screen, for efficiency ListView destroys the item and when scrolling back to that item it recreates it by calling getView() method of adapter so you have to keep an array having a boolean for the status of the button which is by default will be true as for visible and in getView() you just put a check by getting the boolean value of status from the boolean array that if true then item is visible else item is invisible. So when you disappear an item you have to set status of item also false. I assume this is the code in your getView() and you have already defined your array of boolean with same length as items of ListView and value of true with name "yourButtonStatusBooleanArray" then following modifications will work for you.

holder.checkbox = (Button) view.findViewById(R.id.checkBox1);

if(!yourButtonStatusBooleanArray[position])
{
 holder.checkbox.setVisibility(View.INVISIBLE);
}
holder.checkbox.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
holder.checkbox.setVisibility(View.INVISIBLE);
yourButtonStatusBooleanArray[position]=false;


回答2:

Try adding holder.checkbox.setVisibility(View.VISIBLE);after the button declaration



回答3:

This is happening because of view recycling. What you need to do is maintain an array of say booleans and every time a button is clicked toggle the corresponding boolean. Then in your getview check the corresponding boolean array position and set the state of the button.

for more detail reffer this link

check box in listview not working properly

above example is for check box edit your code.



回答4:

You need to implement this method in your ListAdapter which is called every time your View of the row goes from off-screen to on-screen due to the user scrolling the list. The View passed to your getView method may actually be used to display data for a totally different row. This is because the objects are recycled - if you have data for 1,000 rows but only 8 views fit onscreen, the system creates 8 View objects for your rows, not 1,000.

If your class implements ListAdapter you can override the getView method as follows:

public class MyClass implements ListAdapter {

@Override
public View getView(int position, View convertView, ViewGroup parent) {

View rowView = convertView;

//Create a view for this row if none exists yet
if (rowView == null) {
  LayoutInflater inflater = (LayoutInflater) _context
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  rowView = inflater.inflate(R.layout.YOUR_ROW_LAYOUT, parent, false);

//make the button go away if it should not be visible
if (buttonShouldBeNotVisible(convertView)) {  //Your code should determine this
    convertView.checkbox.setVisibility(View.INVISIBLE);  
    //Use View.GONE to make it take up no space
}
return convertView

} }



回答5:

You can do something like this :

public View getView(int position, View convertView, ViewGroup parent) {
        View vi = convertView;
        ViewHolder holder;
        if (convertView == null) {
            vi = inflater.inflate(R.layout.grid_adapter, null);
            holder = new ViewHolder();
            holder.checkbox = (Button) view.findViewById(R.id.checkBox1);
            holder.checkbox.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View arg0) {
                    if (arg0.getTag().equals("0")) {
                        arg0.setVisibility(View.INVISIBLE);
                        arg0.setTag("1");
                    }
                    notifyDataSetChanged();
                }
            });

            vi.setTag(holder);
        } else
            holder = (ViewHolder)vi.getTag();

        try {

            if (holder.checkbox.getTag().equals("1")) {
                holder.checkbox.setVisibility(View.INVISIBLE);
            } else {
                holder.checkbox.setVisibility(View.VISIBLE);
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return vi;
    }


回答6:

The views are recycled in the listview. You will have to save the state of the button in some kind of data structure and set it in the adapters getView(int, View, ViewGroup).

private HashMap<Integer, Boolean> mButtonMap = new HashMap<Integer, Boolean>();

[...]

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View retVal;

    // Do all your stuff with each row



    if (!mButtonMap.containsKey(new Integer(position))) {
        button.setVisibility(View.VISIBLE);
    }
    else {
        button.setVisibility(View.INVISIBLE);
    }
    button.setTag(""+position);
    return retVal;
}

//In your onClickListener
    onClick(View v) {
        [...]
        int position = Integer.parseInt((String) v.getTag());
        mButtonMap.put(position, true); 
        button.setVisibility(View.INVISIBLE);
    }


回答7:

The problem is that the view of the row is reused and therefore after scrolling the row view might be displaying the button with the state of a different row. You could solve this problem by explicitly setting the visibility of your button on initialization of the view. So you would have to remember the state of the row somewhere e.g. in your data object or in an array that keeps track of the already selected items.

holder.checkbox.setVisibility(dataObject.getVisibilityState());

EDIT Answer to comment, shown here to have code blocks

you have to implement the Method yourself, the code was just an example how a custom method could be used. So you could do something like this in you item Class:

 public class Item {
 private int visibility;
 ... other attributes of your item

 public int getVisibilityState(){
  return visibility;
 }

 public void setVisible(){
  visibility = View.VISIBLE;
 }

 public void setInvisible(){
  visibility = View.INVISIBLE;
 }
 }