如何在自定义 ListView 中设置按钮的可见性?
Posted
技术标签:
【中文标题】如何在自定义 ListView 中设置按钮的可见性?【英文标题】:How to set the visibilty of button in a custom ListView? 【发布时间】:2013-04-24 02:11:09 【问题描述】:我有一个带有button
的自定义ListView
,所以当我点击button
时,它应该会消失并且正在消失,但是当我向下滚动并返回时,button
再次出现并且不同button
正在消失。我怎样才能使特定的button
在点击时消失......我正在使用此代码
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】:在 ListView 中,当一个项目离开屏幕时,为了提高效率,ListView 会破坏该项目,当滚动回该项目时,它会通过调用适配器的 getView() 方法重新创建它,因此您必须保留一个具有布尔值的数组来表示状态默认情况下,按钮的默认值为真,因为可见,在 getView() 中,您只需通过从布尔数组中获取状态的布尔值进行检查,如果为真,则项目可见,否则项目不可见。因此,当您消失一个项目时,您必须将项目的状态也设置为 false。 我假设这是您的 getView() 中的代码,并且您已经定义了布尔数组,其长度与 ListView 的项相同,值为 true,名称为“yourButtonStatusBooleanArray”,然后以下修改将适用于您。
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;
【讨论】:
你的意思是“Boolean yourButtonStatusBooleanArray = true”?? boolean[] yourButtonStatusBooleanArray = new boolean[yourListViewItems.size()]; Arrays.fill(yourButtonStatusBooleanArray, true);【参考方案2】:尝试在按钮声明后添加holder.checkbox.setVisibility(View.VISIBLE);
【讨论】:
它有点工作,但是当我向下滚动并返回时,我点击的按钮再次出现...... 这是因为 ListView 重用了资源。尝试查看他们给我的类似问题的答案:***.com/a/15900881/1006156【参考方案3】:这是由于视图回收而发生的。您需要做的是维护一组说布尔值,并且每次单击按钮时都会切换相应的布尔值。然后在您的 getview 中检查相应的布尔数组位置并设置按钮的状态。
更多详情请参考此链接
check box in listview not working properly
以上示例用于复选框编辑您的代码。
【讨论】:
我没有复选框,我有一个按钮,那还能用吗?? 是的。你只需要检查点击按钮的状态。没关系,而是复选框或按钮 只需在代码中添加该链接中标记为“新”的行【参考方案4】:您需要在您的 ListAdapter 中实现此方法,每次您的行视图由于用户滚动列表而从屏幕外变为屏幕时都会调用该方法。传递给 getView 方法的 View 实际上可能用于显示完全不同的行的数据。这是因为对象被回收 - 如果您有 1,000 行的数据,但屏幕上只有 8 个视图适合,系统会为您的行创建 8 个视图对象,而不是 1,000 个。
如果你的类实现了 ListAdapter,你可以重写 getView 方法,如下所示:
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】:你可以这样做:
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】:视图在列表视图中被回收。您必须将按钮的状态保存在某种数据结构中,并将其设置在适配器 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);
【讨论】:
有一个小错误“ListRowAdapter 类型的方法 Integer(int) 未定义”,我该如何解决?? 04-30 09:14:44.463: E/androidRuntime(4214): java.lang.ClassCastException: java.lang.Integer 不能转换为 java.lang.String 04-30 09:14 :44.463: E/AndroidRuntime(4214): at com.envesage.ListRowAdapter$1.onClick(ListRowAdapter.java:341) 奇怪。好吧,试试 'int position = (Integer) v.getTag();'而是。【参考方案7】:问题在于该行的视图被重复使用,因此在滚动该行视图后可能会显示具有不同行状态的按钮。您可以通过在视图初始化时显式设置按钮的可见性来解决此问题。所以你必须记住某处的行的状态,例如在您的数据对象或跟踪已选择项目的数组中。
holder.checkbox.setVisibility(dataObject.getVisibilityState());
编辑对评论的回答,此处显示有代码块
您必须自己实现方法,代码只是一个如何使用自定义方法的示例。所以你可以在你的项目类中做这样的事情:
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;
【讨论】:
我收到一个错误“方法 getVisibilityState() 未定义 Listpublic 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;
以上是关于如何在自定义 ListView 中设置按钮的可见性?的主要内容,如果未能解决你的问题,请参考以下文章