Android 行标记,ViewHolder图案
这是ViewHolder模式的一个简单实现。我有一个包含文章的游标,我想将标题保留在行标记中。在此阶段,我(尝试)将实际字符串和相应的textview保留在行标记中,并将实际字符串保留在textview的标记中Android 行标记,ViewHolder图案,android,row,adapter,Android,Row,Adapter,这是ViewHolder模式的一个简单实现。我有一个包含文章的游标,我想将标题保留在行标记中。在此阶段,我(尝试)将实际字符串和相应的textview保留在行标记中,并将实际字符串保留在textview的标记中 class ArticleListCursorAdapter extends SimpleCursorAdapter { class ViewHolder { String strTitle = null; View viewTitle = nul
class ArticleListCursorAdapter extends SimpleCursorAdapter {
class ViewHolder {
String strTitle = null;
View viewTitle = null;
ViewHolder(View base, String strTitle) {
this.viewTitle = base.findViewById(R.id.textTitle);
this.strTitle = strTitle;
}
@Override
public String toString() {
return new StringBuffer()
.append("strTtitle [").append(strTitle).append("] ")
.append("viewTitle [").append(((TextView)viewTitle).getText()).append("] ")
.append("viewTitle title (tag) [").append(viewTitle.getTag()).append("] ")
.toString();
}
}
public ArticleListCursorAdapter(Context context, int layout, Cursor c, String[] from,
int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
ViewHolder holder = null;
// if (convertView != null)
holder = (ViewHolder)row.getTag();
Log.v(TAG, "getView for [" + position + "]. holder ["
+ (holder == null ? "null holder" : holder.toString()) + "]");
Log.v(TAG, "getView other info: rendering view title ["
+ ((TextView)row.findViewById(R.id.textTitle)).getText()
.toString() + "]");
if (holder == null) {
Cursor cursor = (Cursor)ArticleListCursorAdapter.this.getItem(position);
final String strTitle = cursor.getString(cursor.getColumnIndex(ArticleData.C_TITLE));
holder = new ViewHolder(row, strTitle);
Log.v(TAG, "getView setup onclick for pos [" + position + "] and title ["+ strTitle + "]");
holder.viewTitle.setTag(strTitle);
row.setTag(holder);
}
return row;
}
}
当我运行它时,我希望收到一系列:
getView for [x]. holder [strTitle [7777777] viewTitle [7777777] viewTitle title (tag) [7777777] ]
getView other info: rendering view title [7777777]
如果文章标题是777。我实际上收到的是一种奇怪的价值观组合
(4 items visible at a time, first page)
getView for [0]. holder [null holder]
getView other info: rendering view title [1111111]
getView setup onclick for pos [0] and title [1111111]
getView for [1]. holder [null holder]
getView other info: rendering view title [2222222]
getView setup onclick for pos [1] and title [2222222]
getView for [2]. holder [null holder]
getView other info: rendering view title [3333333]
getView setup onclick for pos [2] and title [3333333]
getView for [3]. holder [null holder]
getView other info: rendering view title [4444444]
getView setup onclick for pos [3] and title [4444444]
(page down)
getView for [4]. holder [strTitle [1111111] viewTitle [5555555] viewTitle title (tag) [1111111] ]
getView other info: rendering view title [5555555]
getView for [5]. holder [null holder]
getView other info: rendering view title [6666666]
getView setup onclick for pos [5] and title [6666666]
one more down
getView for [6]. holder [strTitle [2222222] viewTitle [7777777] viewTitle title (tag) [2222222] ]
getView other info: rendering view title [7777777]
getView for [7]. holder [strTitle [3333333] viewTitle [8888888] viewTitle title (tag) [3333333] ]
getView other info: rendering view title [8888888]
getView for [8]. holder [strTitle [4444444] viewTitle [9999999] viewTitle title (tag) [4444444] ]
getView other info: rendering view title [9999999]
(scroll up)
getView for [4]. holder [strTitle [4444444] viewTitle [5555555] viewTitle title (tag) [4444444] ]
getView other info: rendering view title [5555555]
getView for [3]. holder [strTitle [3333333] viewTitle [4444444] viewTitle title (tag) [3333333] ]
getView other info: rendering view title [4444444]
(scroll up again)
getView for [2]. holder [strTitle [1111111] viewTitle [3333333] viewTitle title (tag) [1111111] ]
getView other info: rendering view title [3333333]
getView for [1]. holder [strTitle [2222222] viewTitle [2222222] viewTitle title (tag) [2222222] ]
getView other info: rendering view title [2222222]
getView for [0]. holder [strTitle [6666666] viewTitle [1111111] viewTitle title (tag) [6666666] ]
getView other info: rendering view title [1111111]
1/为什么ViewHolder的字符串部分不断变化?
2/viewTitle TextView如何更改其标记内容(上面的5555555 viewTitle的标记中一次有1111111,另一次有444444)适配器回收视图以节省资源。设想一个有1000行的ListView:为每行创建一个唯一的视图会很慢,而且没有必要。因此适配器只创建足够的可见视图,再加上一些用于滚动的视图;并且简单地重复使用这些可回收的行 您看到的是,您已经为每个可循环行(0-3)设置了一个ViewHolder,但是当您滚动文本视图时,它会改变以反映列表数据。这就是为什么可回收行#0具有行#0的
strTitle
值,而实际行#4具有文本视图
从评论中添加内容
理论上,我可以为我的1000行制作1000个[viewholder]
是的,您可以,但就像有1000个唯一行一样,这是多余的。我想提出一种更有效的方法来做你想做的事:
class ArticleListCursorAdapter extends SimpleCursorAdapter {
private int cTitleIndex;
public ArticleListCursorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to) {
super(context, layout, cursor, from, to, 0);
// Rather than check for the column index of C_TITLE every time
// you use getView(), we check it only once.
cTitleIndex = cursor.getColumnIndex(ArticleData.C_TITLE);
}
// This method binds the Cursor data to your row
@Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
ViewHolder holder = (ViewHolder) view.getTag();
// Create a new ViewHolder for each recyclable row
if(holder == null) {
holder = new ViewHolder();
holder.viewTitle = (TextView) view.findViewById(R.id.textTitle);
view.setTag(holder);
}
// Update this value each time the row is recycled, we do this in
// bindView() because we already have access to the Cursor
holder.strTitle = cursor.getString(cTitleIndex);
// I'm not sure what this does but I kept it
holder.viewTitle.setTag(holder.strTitle);
}
public class ViewHolder {
String strTitle;
// Changed viewTitle to a TextView to unnecessary conversions in this example
TextView viewTitle;
}
}
我将所有内容从getView()移动到bindView()。在游标适配器中,getView()方法调用bindView(),这是与游标相关的所有数据发生的地方。由于大多数代码都与光标相关,因此在此处移动代码可以节省在getView()中查找光标的额外工作。您仍然可以重写getView()并调用ViewHolder,但在这种情况下不再需要它
我还退出了对列索引的搜索,以停止那里的额外工作。(要知道这并不完美,调用adapter.changeCursor()之类的方法可能会重新排列列索引,因此需要重新检查索引。但这是一个基本示例,我不想过度考虑。)
现在,如果您将LogCat语句添加回,您会注意到,当您上下滚动时,该行将保留匹配111111和111111以及444444和444444对。希望能澄清一些事情 我对您所做工作的基本原则感到困惑,为什么不在您的
数组中从[]
和传递ArticleData.C_TITLE
和R.id.textTitle
?这不是SimpleCorsOrAdapter已经做过的,将列绑定到视图吗?我想做的是处理一些小部件上的点击。所以我重写了适配器,实现了ViewHandler模式。在getView中,我使用OnClick方法中的strTitle创建一个OnClick侦听器。但情况一直在变化。因此,我试图了解整个ViewHandler/getTag概念是如何工作的。我想当我通过一排标签中的某个东西时,我会在那里找到它。这表明我在我的意图中遗漏了什么,这是一种预期的行为吗?我的意思是,保存“55555”字符串的TextView应该附带任意标记???嗯。所以你是说我没有每行一个ViewHandler(理论上我可以为我的1000行制作1000个),而是每可见行一个(在本例中为4个)。谢谢山姆的澄清。