Listview嵌套gridview条目,在Listview的Adapter中实现gridview的条目点击notifyDataSetChanged()失效

程序猿的那点事 2016-12-12 09:18:11
这是Listview的Adapter . adapter.notifyDataSetChanged();方法失效

/**
* 商品详情sku适配器
* Created by kxx on 2016/12/10.
*/

public class GoodsDetailSkuAdapter extends BaseAdapter{
private final Activity context;
List<GoodsBean.SkuArray> skuArray;
private GoodsDetailSkuGridAdapter adapter;

private int size = 0;
private int color = 0;
private int style = 0;
//接口回调
SkuInterface skuListener;

public GoodsDetailSkuAdapter(Activity context, List<GoodsBean.SkuArray> skuArray,SkuInterface skuListener) {
this.skuArray = skuArray;
this.context = context;
this.skuListener = skuListener;
}
@Override
public int getCount() {
return skuArray.size();
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}


@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = UiUtils.inflate(R.layout.item_goods_detail_sku);
holder.tv_dialog_sku_title = (TextView) convertView.findViewById(R.id.tv_dialog_sku_title);
holder.gv_dialog_properties = (MyGridView) convertView.findViewById(R.id.gv_dialog_properties);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv_dialog_sku_title.setText(skuArray.get(position).name);
adapter = new GoodsDetailSkuGridAdapter(skuArray.get(position).val);
holder.gv_dialog_properties.setAdapter(adapter);

holder.gv_dialog_properties.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int sposition, long id) {
if(skuArray.get(position).title.equals("chima")){
adapter.setClickPosition(sposition);
size = Integer.parseInt(skuArray.get(position).val.get(sposition).id);
int sizeId = skuArray.get(position).id;
skuListener.setSkuSize(sizeId+":"+size);
adapter.notifyDataSetChanged();
}else if(skuArray.get(position).title.equals("yanse")){
adapter.setClickPosition(sposition);
color = Integer.parseInt(skuArray.get(position).val.get(sposition).id);
int colorId = skuArray.get(position).id;
skuListener.setSkuColor(colorId+":"+color);
adapter.notifyDataSetChanged();
}else if(skuArray.get(position).title.equals("kuanshi")){
adapter.setClickPosition(sposition);
style = Integer.parseInt(skuArray.get(position).val.get(sposition).id);
int styleId = skuArray.get(position).id;
skuListener.setSkuStyle(styleId+":"+style);
adapter.notifyDataSetChanged();
}
}
});
return convertView;
}



private class ViewHolder{
TextView tv_dialog_sku_title;

MyGridView gv_dialog_properties;
}


}


这是gridview的adapter

/**
* sku条目适配器
* Created by kxx on 2016/12/10.
*/

public class GoodsDetailSkuGridAdapter extends BaseAdapter {
private List<GoodsBean.SkuArray.Val> val = new ArrayList<>();

private int clickPosition = -1;

public GoodsDetailSkuGridAdapter(List<GoodsBean.SkuArray.Val> val) {
this.val = val;
}

@Override
public int getCount() {
return val.size();
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}

public void setClickPosition(int position){
this.clickPosition = position;
}


@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = UiUtils.inflate(R.layout.item_sku_text_normal);
holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv_name.setText(val.get(position).rename);

if(position == clickPosition){
//Toast.makeText(UiUtils.getContext(), "执行刷新", Toast.LENGTH_SHORT).show();
holder.tv_name.setBackgroundResource(R.drawable.shape_sku_text_pressed_bg);
holder.tv_name.setTextColor(Color.WHITE);
}else {
holder.tv_name.setBackgroundResource(R.drawable.shape_sku_text_normal_bg);
holder.tv_name.setTextColor(Color.rgb(109,109,109));
}

return convertView;
}

private class ViewHolder{
public TextView tv_name;
}
}


其他方法都没事,只有adapter.notifyDataSetChanged();没有用。求各路大神给解决方法。

现在是要实现条目的点击效果,点击的地方变红,adapter.notifyDataSetChanged();这个方法不执行,无法刷新。
...全文
222 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
yifzzzz 2020-09-16
  • 打赏
  • 举报
回复
那Recyclerview嵌套gridview条目,在Reclcyerview的Adapter中实现gridview的条目点击notifyDataSetChanged()失效,请问怎么解决
Cao_XiLin 2018-10-10
  • 打赏
  • 举报
回复
如果数据多的话会很卡怎么办
  • 打赏
  • 举报
回复
引用 1 楼 yanzhenjie1003 的回复:
ListView的每个item都有一个GridView,所以GridView的Adapter如果写成ListView的Adapter的成员变量,那么ListView的上一个Item的GridView的Adapter就会被下一个Item的GridView的Adapter覆盖掉,所以当点击GridView的Item的时候去调用adapter.notify...的时候实际是调用了ListView的最后一个Item的GridView的Adapter.notify,所以你点记得时候adapter.notify实际是刷新了最后一个,所以看起来是无效的。 正确是方式应该是ListView的每个Item都要写成局部成员变量并且加final修饰,具体代码如下:

    // private GoodsDetailSkuGridAdapter adapter; // 这一行代码注释了。

    ...

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView == null){
            holder = new ViewHolder();
            convertView = UiUtils.inflate(R.layout.item_goods_detail_sku);
            holder.tv_dialog_sku_title = (TextView) convertView.findViewById(R.id.tv_dialog_sku_title);
            holder.gv_dialog_properties = (MyGridView) convertView.findViewById(R.id.gv_dialog_properties);
            convertView.setTag(holder);
        }else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tv_dialog_sku_title.setText(skuArray.get(position).name);
        final GoodsDetailSkuGridAdapter adapter = new GoodsDetailSkuGridAdapter(skuArray.get(position).val);
        holder.gv_dialog_properties.setAdapter(adapter);
 
        holder.gv_dialog_properties.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int sposition, long id) {
                if(skuArray.get(position).title.equals("chima")){
                    adapter.setClickPosition(sposition);
                    size = Integer.parseInt(skuArray.get(position).val.get(sposition).id);
                    int sizeId = skuArray.get(position).id;
                    skuListener.setSkuSize(sizeId+":"+size);
                    adapter.notifyDataSetChanged();
                }else if(skuArray.get(position).title.equals("yanse")){
                    adapter.setClickPosition(sposition);
                    color = Integer.parseInt(skuArray.get(position).val.get(sposition).id);
                    int colorId = skuArray.get(position).id;
                    skuListener.setSkuColor(colorId+":"+color);
                    adapter.notifyDataSetChanged();
                }else if(skuArray.get(position).title.equals("kuanshi")){
                    adapter.setClickPosition(sposition);
                    style = Integer.parseInt(skuArray.get(position).val.get(sposition).id);
                    int styleId = skuArray.get(position).id;
                    skuListener.setSkuStyle(styleId+":"+style);
                    adapter.notifyDataSetChanged();
                }
            }
        });
        return convertView;
    }
严大出马一个顶俩。notifyDataSetChanged();不刷新的问题已经解决了。
严振杰 2016-12-12
  • 打赏
  • 举报
回复
ListView的每个item都有一个GridView,所以GridView的Adapter如果写成ListView的Adapter的成员变量,那么ListView的上一个Item的GridView的Adapter就会被下一个Item的GridView的Adapter覆盖掉,所以当点击GridView的Item的时候去调用adapter.notify...的时候实际是调用了ListView的最后一个Item的GridView的Adapter.notify,所以你点记得时候adapter.notify实际是刷新了最后一个,所以看起来是无效的。 正确是方式应该是ListView的每个Item都要写成局部成员变量并且加final修饰,具体代码如下:

    // private GoodsDetailSkuGridAdapter adapter; // 这一行代码注释了。

    ...

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView == null){
            holder = new ViewHolder();
            convertView = UiUtils.inflate(R.layout.item_goods_detail_sku);
            holder.tv_dialog_sku_title = (TextView) convertView.findViewById(R.id.tv_dialog_sku_title);
            holder.gv_dialog_properties = (MyGridView) convertView.findViewById(R.id.gv_dialog_properties);
            convertView.setTag(holder);
        }else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tv_dialog_sku_title.setText(skuArray.get(position).name);
        final GoodsDetailSkuGridAdapter adapter = new GoodsDetailSkuGridAdapter(skuArray.get(position).val);
        holder.gv_dialog_properties.setAdapter(adapter);
 
        holder.gv_dialog_properties.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int sposition, long id) {
                if(skuArray.get(position).title.equals("chima")){
                    adapter.setClickPosition(sposition);
                    size = Integer.parseInt(skuArray.get(position).val.get(sposition).id);
                    int sizeId = skuArray.get(position).id;
                    skuListener.setSkuSize(sizeId+":"+size);
                    adapter.notifyDataSetChanged();
                }else if(skuArray.get(position).title.equals("yanse")){
                    adapter.setClickPosition(sposition);
                    color = Integer.parseInt(skuArray.get(position).val.get(sposition).id);
                    int colorId = skuArray.get(position).id;
                    skuListener.setSkuColor(colorId+":"+color);
                    adapter.notifyDataSetChanged();
                }else if(skuArray.get(position).title.equals("kuanshi")){
                    adapter.setClickPosition(sposition);
                    style = Integer.parseInt(skuArray.get(position).val.get(sposition).id);
                    int styleId = skuArray.get(position).id;
                    skuListener.setSkuStyle(styleId+":"+style);
                    adapter.notifyDataSetChanged();
                }
            }
        });
        return convertView;
    }
通过封装BaseAdapter和RecyclerView.Adapter得到的通用的,简易的Adapter。项目地址:https://github.com/tianzhijiexian/CommonAdapter 效果图:已解决的问题 提升item的独立性,完美支持item被多处复用 item会根据type来做自动复用 支持多种类型的item 一个item仅会调用一次setViews(),避免重复建立监听器 一个item仅会触发一次绑定视图的操作,提示效率 支持dataBinding和其他第三方注入框架 提供了getView()方法来简化findViewById 支持通过item的构造方法来传入Activity对象 支持通过item的构造方法来传入item事件的回调 提供了getConvertedData(data, type)方法来对item传入的数据做转换,方便拆包和提升item的复用性 支持viewpager的正常加载模式和懒加载 支持快速将listview的适配器切换为recyclerView的适配器 viewpager的notifyDataSetChanged可以正常更新界面 支持recyclerView的添加头部和底部 支持适配器的数据自动绑定,只用操作数据便可,adapter会自动notify界面零、重要接口adapter的item必须实现此接口,接口源码如下:public interface AdapterItem {     /**      * @return item布局文件的layoutId      */     @LayoutRes     int getLayoutResId();     /**      * 初始化views      */     void bindViews(final View root);     /**      * 设置view的参数      */     void setViews();     /**      * 根据数据来设置item的内部views      *      * @param model    数据list内部的model      * @param position 当前adapter调用item的位置      */     void handleData(T model, int position); }例子:public class TextItem implements AdapterItem {     @Override     public int getLayoutResId() {         return R.layout.demo_item_text;     }     TextView textView;     @Override     public void bindViews(View root) {         textView = (TextView) root.findViewById(R.id.textView);     }     @Override     public void setViews() { }     @Override     public void handleData(DemoModel model, int position) {         textView.setText(model.content);     } }一、ListView GridView的通用适配器——CommonAdapter只需继承CommonAdapter便可实现适配器:listView.setAdapter(new CommonAdapter(data, 1) {     public AdapterItem createItem(Object type) {         return new TextItem();     } });二、RecyclerView的通用适配器——CommonRcvAdapter通过继承CommonRcvAdapter实现适配器:mAdapter = new CommonRcvAdapter(data) {  public AdapterItem createItem(Object type) {         return new TextItem();   } };三、ViewPager的通用适配器——CommonPagerAdapter通过继承CommonPagerAdapter实现适配器:viewPager.setAdapter(new CommonPagerAdapter() {     public AdapterItem createItem(Object type) {         return new TextItem();     } });设计思路1. Adapter如果用adapter常规写法,你会发现代码量很大,可读性低。如果adapter有多个类型的Item,我们还得在getView()写很多if-else语句,很乱。 而现在我让adapter的代码量减少到一个8行的内部类,如果你需要更换item只需要动一行代码,真正实现了可插拔化。最关键的是item现在作为了一个独立的对象,可以方便的进行复用。2. AdapterItem和原来方式最为不同的一点就是我把adapter的item作为了一个实体,这种方式借鉴了RecyclerViewViewHolder的设计。把item作为实体的好处有很多,比如复用啊,封装啊,其余的就不细说了。3. 分层在使用过程,我发现如果adapter放在view层,那就会影响到view层的独立性。此外adapter经常有很多数据处理的操作,比如通过type选择item,数据的拆包、转换等操作。于是我还是推荐把adapter放在mvp的p层,或者是mvvm的m层。通过在实际的项目使用来看,放在m或p层的效果较好,view的复用也比较好做。

80,351

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧