在 ListView 中滚动时 CheckedTextView 消失
Posted
技术标签:
【中文标题】在 ListView 中滚动时 CheckedTextView 消失【英文标题】:CheckedTextView disappears when scroll in ListView 【发布时间】:2015-04-27 04:39:32 【问题描述】:我有自定义 ListView。我正在使用数组适配器来填充我的 ListViews 行。它工作得很好。当我选择 ListView 行时,我的 checkedtextview 变得可见。滚动我检查的情况后消失。 我怎样才能记住我的支票?
感谢您的帮助。
这是我的适配器
package test.cbsmobil.ibb;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.TextView;
import java.util.ArrayList;
public class ListViewItemsAdapter extends ArrayAdapter<Item>
private Context context;
private ArrayList<Item> items;
private LayoutInflater vi;
private int resLayout;
private CheckedTextView ctv;
private int selectedIndex;
public ListViewItemsAdapter(Context context, ArrayList<Item> items)
super(context, 0, items);
this.context = context;
this.items = items;
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
selectedIndex = -1;
@Override
public long getItemId(int position)
return position;
@Override
public View getView(int position, View convertView, ViewGroup parent)
View v = convertView;
final Item i = items.get(position);
if (i != null)
if (i.isSection())
ListViewItemsSection si = (ListViewItemsSection) i;
v = vi.inflate(R.layout.list_item_section, null);
v.setOnClickListener(null);
v.setOnLongClickListener(null);
v.setLongClickable(false);
final TextView sectionView = (TextView) v.findViewById(R.id.list_item_section_text);
sectionView.setText(si.getTitle());
else
ListViewItems ei = (ListViewItems) i;
v = vi.inflate(R.layout.list_item_entry,null);
final TextView title = (TextView) v.findViewById(R.id.list_item_entry_title);
if (title != null)
title.setText(ei.title);
return v;
这是我的 MainActivity; 让我解释一下这个活动代码块。 layerlist 是我的 ListView。我在 ListView 中使用多项选择模式进行多项选择。
layerlist.setAdapter(adapter);
layerlist.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
layerlist.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
if(!items.get(position).isSection())
ListViewItems item = (ListViewItems) items.get(position);
//adapter.setSelectedIndex(position);
Log.d("ListView", "Position " + item.toString());
//View v = layerlist.getChildAt(position);
View v = getViewByPosition(position,layerlist);
CheckedTextView ctv = (CheckedTextView) v.findViewById(R.id.ctv);
if (!ctv.isChecked())
ctv.setChecked(true);
Log.d("Checked", "Açıldı" + " " + ctv.isChecked());
else
ctv.setChecked(false);
Log.d("Checked", "Kapandı" + " " + ctv.isChecked());
);
return rootView;
private View getViewByPosition(int pos, ListView listView)
final int firstListItemPosition = listView.getFirstVisiblePosition();
final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;
if (pos < firstListItemPosition || pos > lastListItemPosition )
return listView.getAdapter().getView(pos, null, listView);
else
final int childIndex = pos - firstListItemPosition;
return listView.getChildAt(childIndex);
【问题讨论】:
【参考方案1】:您应该使用developer.android.com 中描述的“视图持有者”设计模式,并在this post 上进行了详细说明。
这里最重要的是:
-
创建 ViewHolder 类;
如果 convertView 为空,则将 ViewHolder 实例存储在标签中;
如果不是,则从标签中恢复 ViewHolder 实例。
这是我的适配器的代码:
package br.com.inovant.pm;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import java.util.List;
public class ContactsAdapter extends ArrayAdapter<CheckedContact>
public ContactsAdapter(Context context, List<CheckedContact> contacts)
super(context, 0, contacts);
static class ViewHolder
protected CheckedTextView checkedTextView;
@Override
public View getView(int position, View convertView, ViewGroup parent)
ViewHolder viewHolder;
if (convertView == null)
convertView = LayoutInflater.from(getContext()).inflate(android.R.layout.select_dialog_multichoice, parent, false);
viewHolder = new ViewHolder();
viewHolder.checkedTextView = (CheckedTextView) convertView.findViewById(android.R.id.text1);
convertView.setTag(viewHolder);
else
viewHolder = (ViewHolder) convertView.getTag();
final CheckedContact checkedContact = getItem(position);
final CheckedTextView checkedTextView = viewHolder.checkedTextView;
checkedTextView.setText(checkedContact.getContact().getDisplayName());
checkedTextView.setChecked(checkedContact.isChecked());
return convertView;
@Override
public long getItemId(int position)
return getItem(position).getContact().getId().hashCode();
@Override
public boolean hasStableIds()
return true;
【讨论】:
【参考方案2】:我遇到了同样的问题,所以我在自定义适配器中使用了以下方法,我得到了解决方案。
在您的 ListViewItemsAdapter 中添加以下方法:
@Override
public int getCount()
return alUpgradeTour.size();
@Override
public int getItemViewType(int position)
return position;
@Override
public int getViewTypeCount()
return getCount();
试试看,你也会得到解决的。
【讨论】:
我没有得到解决方案。 :( 我将 alUpgradeTour.size 更改为我的 arrayadapter 大小。但我买不起。【参考方案3】:Android 的 ListView 会回收其所有单独的视图,也就是说,当一个列表项从屏幕上滚出时,它的视图会被回收以供刚刚滚动到可见屏幕区域的视图使用。现在,当一个较旧的列表项滚动回视图时,它会获得一些其他回收的视图来绘制自己。 因此,复选标记丢失或任何已更改/更新的数据。
解决方案是您将更改保存在列表项中,在您的情况下 - ListViewItems。假设您在 ListViewItems 的类定义和调用 setChecked 方法的 onItemClick 中有一个标志 boolean isChecked = false
,设置 isChecked = true
这将帮助您保留复选标记。
希望对你有帮助。
【讨论】:
以上是关于在 ListView 中滚动时 CheckedTextView 消失的主要内容,如果未能解决你的问题,请参考以下文章
WPF:如何在拖动 ListView 项目时允许在 ListView 中使用鼠标滚轮滚动?
在 ListView 中滚动时 CheckedTextView 消失