Android ViewHolder图案-如何正确更新视图

Android ViewHolder图案-如何正确更新视图,android,listview,android-viewholder,Android,Listview,Android Viewholder,在扩展ArrayAdapter中实现viewHolder模式,并在线性布局上实现onClickListener时,此LinearLayout的背景色会发生更改,但对于其他随机行也是如此 这是我的代码(已将viewHolder拆分为仅包含错误): 公共类CustomFeedsAdapter扩展了ArrayAdapter{ 私有静态最终字符串标记=“CustomFeedsAdapter”; 私人语境; 私人ArrayList客户社区问题; 公共CustomFeedsAdapter(上下文、Array

在扩展ArrayAdapter中实现viewHolder模式,并在线性布局上实现onClickListener时,此LinearLayout的背景色会发生更改,但对于其他随机行也是如此

这是我的代码(已将viewHolder拆分为仅包含错误):

公共类CustomFeedsAdapter扩展了ArrayAdapter{
私有静态最终字符串标记=“CustomFeedsAdapter”;
私人语境;
私人ArrayList客户社区问题;
公共CustomFeedsAdapter(上下文、ArrayList customCommunityQuestions){
超级(上下文,-1,客户社区问题);
this.context=上下文;
this.customCommunityQuestions=customCommunityQuestions;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
视图行视图=转换视图;
//重用视图
最终持票人;
if(convertView==null){
holder=新的ViewHolder();
LayoutFlater充气器=(LayoutFlater)context.getSystemService(context.LAYOUT\u充气器\u服务);
rowView=充气机。充气(R.layout.cards\u feeds\u row,null,false);
holder.buttonFollow=(LinearLayout)rowView.findViewById(R.id.follow\U布局);
rowView.setTag(支架);
}否则{
holder=(ViewHolder)rowView.getTag();
}
最终CustomCommunityQuestion currentQuestion=customCommunityQuestions.get(位置);
//设置onClick侦听器
holder.buttonFollow.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
截击单例截击单例=截击单例.getInstance(上下文);
StringRequest followJsonObjectRequest=新StringRequest(Request.Method.GET,
"http://private-e9644-popxoandroid.apiary-mock.com/quest_follow/1/0",
新的Response.Listener(){
@凌驾
公共void onResponse(字符串响应){
试一试{
Log.d(标签、响应);
JSONObject responseObject=新的JSONObject(响应);
字符串消息=responseObject.getString(“消息”);
整数成功=responseObject.getInt(“成功”);
Toast.makeText(上下文、消息、Toast.LENGTH_SHORT).show();
如果(成功!=0){
holder.buttonFollow.setBackgroundColor(R.color.holo_blue_bright);//这里我想要更新的按钮没有得到颜色,而是一些奇怪的随机行的按钮被更改了。
holder.buttonFollow.setEnabled(错误);
}
}捕获(例外e){
e、 printStackTrace();
}
}
},
新的Response.ErrorListener(){
@凌驾
公共无效onErrorResponse(截击错误){
Toast.makeText(上下文,“出现了一些错误!您无法理解”,Toast.LENGTH_SHORT.show();
错误。printStackTrace();
Log.e(标记,error.getMessage());
}
});
addToRequestQueue(followJsonObjectRequest);
}
});
返回行视图;
}
私有类视窗持有者{
私人线路布局按钮如下;
}
}

问题在于列表项的回收:

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

    // reuse views
    final ViewHolder holder;
    if (convertView == null) {
        ...
    } else {
        holder = (ViewHolder) rowView.getTag();
        //!!!
        // here the view item is recycled but
        // holder.buttonFollow is not reset to its initial state
    }

解决方案:您的
CustomFeedsAdapter
必须记住每个项目的成功统计数据

您正在做什么

当前可见的行位于位置0,1,2。您正在更新已设置为特定(用于更好的词)视图标记的特定ViewHolder。随后,当您调用
holder=(ViewHolder)rowview.getTag()
时,将重新使用此视图。为了便于解释,我们假设您正在更新位置1处的视图

滚动列表视图时会发生什么情况

滚动listview时,旧视图将通过从标记中获取保持架来重新使用。这意味着您先前更改的视图现在正在重新使用

您需要做些什么

因此,当您需要更新视图时,首先更新相关变量。例如:

在CustomCommunityQuestion类中创建一个属性,并实现如下getter和setter:

boolean isBlue;

public void setIsBlue(booelan isblue){
     this.isBlue = isblue;
}

public boolean isBlue(){
    return isBlue;
} 
现在,在单击Listener的按钮中,可以将变量isBlue设置为yes,并调用
notifyDataSetChanged()
。此外,处理属性为蓝色,如下所示:

只需检查isBlue状态并相应设置颜色


希望有帮助

嘿,萨凯特,你可以参考这个。有人添加了一条评论,我认为这是一个正确的答案。说真的,我从来没有使用过POJO类,我更喜欢的是在你的onclick侦听器中下载你想要的任何东西,然后不更新那里的UI,而是更新适配器的数据集,并使用notifyDataSetChanged()重新加载列表;在getView中处理UI,仅此而已。相信我,我在我的项目中使用了相同的解决方案:)@sandeppebhandari:Hmmm。。有点道理,但如果可能的话,我宁愿将UI功能与核心类分开。让我们看看一些答案是否能帮我解决这个问题。谢谢k3b。我想我明白你的意思了。然而,你能告诉我是否有一个最佳实践批准
boolean isBlue;

public void setIsBlue(booelan isblue){
     this.isBlue = isblue;
}

public boolean isBlue(){
    return isBlue;
} 
if(customCommunityQuestions.get(position).isBlue()){
       holder.buttonFollow.setBackgroundColor(R.color.holo_blue_bright);
}else{
     holder.buttonFollow.setBackgroundColor(R.color.black);
}