草庐IT

android - Recycler View 不保存 View 状态

coder 2023-12-20 原文

我正在处理 Recycler View ,在其中我在适配器中使用 LinearLayout。当点击 LinearLayout 时,它隐藏了 View 并同样再次点击使其可见。我的问题是 Recycler View 没有保存 View 的状态,当我滚动时它再次刷新 View ,再次更改初始时间的状态 View 。

下面给出了我的 RecyclerView 代码和我的适配器。

RecyclerView 代码:

 LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
  Menu_Detail_Adapter  searchabledapter = new Menu_Detail_Adapter(getActivity());
   RecyclerView mRecyclerView =(RecyclerView)view.findViewById(R.id.recycler_view);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setItemViewCacheSize(2);
    mRecyclerView.setAdapter(searchabledapter);
    mRecyclerView.setLayoutManager(layoutManager);

我的适配器代码:

public class Menu_Detail_Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {


    public Menu_Detail_Adapter(Context context1) {
        arrayList = new ArrayList<>();
        arrlist = new ArrayList<>();
        context = context1;
    }




    @Override
    public RecyclerView.ViewHolder  onCreateViewHolder(ViewGroup parent, int viewType) {


            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.kasib_o_karahi_list_view, parent, false);
            return new MemberViewHolder(view, onItemClickListener);

    }



    String imageUrl = "";
    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder  holder, int position) {

        final ParseObject parseObject = arrayList.get(position);

        if(holder instanceof  MemberViewHolder){

            if (arrayList.size() > 0) {
                try {

                    ((MemberViewHolder) holder).linear_layout__add.setVisibility(View.VISIBLE);
                    ((MemberViewHolder) holder).linear_layout_add_subtract_buttons.setVisibility(View.GONE);

                    // Here I am facing a problem

                    // On both LinearLayout click listeners when I am scrolling it 
is again changing my View States


                    ((MemberViewHolder) holder).rrl_add.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ((MemberViewHolder) holder).linear_layout__add.setVisibility(View.GONE);
                            ((MemberViewHolder) holder).linear_layout_add_subtract_buttons.setVisibility(View.VISIBLE);
                        }
                    });

                    ((MemberViewHolder) holder).rrl_minus.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ((MemberViewHolder) holder).linear_layout__add.setVisibility(View.VISIBLE);
                            ((MemberViewHolder) holder).linear_layout_add_subtract_buttons.setVisibility(View.GONE);
                        }
                    });

                    ((MemberViewHolder) holder).rrl_add_btn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {

                        }
                    });



                } catch (Exception e) {
                    e.getMessage();
                }
            }
        }
    }

    @Override
    public int getItemCount() {
        return arrayList == null ? 0 : arrayList.size();
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
    }




    static class MemberViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView txtTitle;
        TextView txtDescription;
        TextView txtCountry;
        OnItemClickListener onItemClickListener;
        ImageView imgDescription;

        LinearLayout linear_layout_add_subtract_buttons, linear_layout__add;
        RelativeLayout rrl_add, rrl_minus, rrl_add_btn;

        public MemberViewHolder(View itemView, OnItemClickListener onItemClickListener) {
            super(itemView);
            linear_layout_add_subtract_buttons = (LinearLayout) itemView.findViewById(R.id.add_subtract_buttons);
            linear_layout__add                 = (LinearLayout) itemView.findViewById(R.id.ll_add);
            rrl_add              = (RelativeLayout) itemView.findViewById(R.id.rrl_add);
            rrl_minus            = (RelativeLayout) itemView.findViewById(R.id.rrl_minus);
            rrl_add_btn          = (RelativeLayout) itemView.findViewById(R.id.rrl_add_btn);


            itemView.setOnClickListener(this);
            this.onItemClickListener = onItemClickListener;
        }

        @Override
        public void onClick(View v) {
            onItemClickListener.onItemClick(v, getAdapterPosition());
        }
    }

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }


}

最佳答案

一个问题是您的代码既不精简也不完整且可验证。所以我不得不编一个例子,你必须根据自己的需要采用它。

我所说的“单个对象数组”由 DataItem 类的对象组成与一个int和两个 boolean s 成员。

public class DataItem{
    int dataItem;
    boolean visible1;
    boolean visible2;

    public DataItem(int dataItem, boolean visible1, boolean visible2){
        this.dataItem = dataItem;
        this.visible1 = visible1;
        this.visible2 = visible2;
    }
}

onCreate()在我的 Activity 中看起来像这样:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);

    int dataItemsLength = 50;
    ArrayList<DataItem> dataItems = new ArrayList<>();
    for (int i = 0; i < dataItemsLength; i++) {
        dataItems.add(new DataItem(i, true, true));
    }
    RecyclerView rv = findViewById(R.id.rv);
    Menu_Detail_Adapter adapter = new Menu_Detail_Adapter(this, dataItems);
    rv.setLayoutManager(new LinearLayoutManager(this));
    rv.setAdapter(adapter);
}

虽然在您的代码中不清楚您的数据来自何处,但在这里我选择了在 Activity 中“制作”数据(您可能想要“读取”它)并将其传递给适配器的方法。原则上,您也可以在适配器内部执行此操作。

我为 RecyclerView 使用了一个非常简单的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</RelativeLayout>

项目的布局稍微复杂一些:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/rl1"
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:background="@android:color/holo_orange_light">

       <TextView
            android:id="@+id/tv1"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/rl2"
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:background="@android:color/holo_orange_dark">

        <TextView
            android:id="@+id/tv2"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>
</LinearLayout>

最重要的是,适配器:

public class Menu_Detail_Adapter extends RecyclerView.Adapter<Menu_Detail_Adapter.ViewHolder> {
    private ArrayList<DataItem> dataItems;
    private final LayoutInflater inflater;

    Menu_Detail_Adapter(Context context, ArrayList<DataItem> dataItems) {
        this.dataItems = new ArrayList<>();
        this.dataItems.addAll(dataItems);
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(inflater.inflate(R.layout.list_item, parent, false));
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.rl1.setVisibility(dataItems.get(position).visible1 ? View.VISIBLE : View.INVISIBLE);
        holder.tv1.setText(String.valueOf(dataItems.get(position).dataItem));
        holder.rl2.setVisibility(dataItems.get(position).visible2 ? View.VISIBLE : View.INVISIBLE);
    }

    @Override
    public int getItemCount() {
        return dataItems.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        RelativeLayout rl1, rl2;
        TextView tv1;

        ViewHolder(View itemView) {
            super(itemView);
            rl1 = itemView.findViewById(R.id.rl1);
            rl2 = itemView.findViewById(R.id.rl2);
            rl1.setOnClickListener(this);
            rl2.setOnClickListener(this);
            tv1 = itemView.findViewById(R.id.tv1);
            ((TextView) itemView.findViewById(R.id.tv2)).setText("default");
        }

        @Override
        public void onClick(View view) {
            if (view.getId() == R.id.rl1) {
                if (view.getVisibility() == View.VISIBLE) {
                    view.setVisibility(View.INVISIBLE);
                    dataItems.get(getAdapterPosition()).visible1 = false;
                } else {
                    view.setVisibility(View.VISIBLE);
                    dataItems.get(getAdapterPosition()).visible1 = true;
                }
            } else if (view.getId() == R.id.rl2) {
                if (view.getVisibility() == View.VISIBLE) {
                    view.setVisibility(View.INVISIBLE);
                    dataItems.get(getAdapterPosition()).visible2 = false;
                } else {
                    view.setVisibility(View.VISIBLE);
                    dataItems.get(getAdapterPosition()).visible2 = true;
                }
            }
        }
    }
}

关于适配器的一些评论:

  • 确保不要对 onBindViewHolder() 中的任何可见性进行硬编码。请改用您的数据集。

  • 附上 onClickListener s ViewHolder 的构造函数中 类。如果您愿意,可以将监听器添加为匿名类,并避免统一 onClick 的 if 子句。方法。这主要是品味问题。

  • 在监听器内部,注意同时执行以下操作:刷新 View 和更新模型。这是关键点。

  • 出于您的目的,请勿使用 notifyDataSetChanged .只有在添加或删除 DateItem 时才需要这样做来自 ArrayList<DataItem>称为 dataItems .

关于android - Recycler View 不保存 View 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47104414/

有关android - Recycler View 不保存 View 状态的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  3. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  4. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  5. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  6. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  7. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  8. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  9. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  10. ruby-on-rails - 复数 for fields_for has_many 关联未显示在 View 中 - 2

    目前,Itembelongs_toCompany和has_manyItemVariants。我正在尝试使用嵌套的fields_for通过Item表单添加ItemVariant字段,但是使用:item_variants不显示该表单。只有当我使用单数时才会显示。我检查了我的关联,它们似乎是正确的,这可能与嵌套在公司下的项目有关,还是我遗漏了其他东西?提前致谢。注意:下面的代码片段中省略了不相关的代码。编辑:不知道这是否相关,但我正在使用CanCan进行身份验证。routes.rbresources:companiesdoresources:itemsenditem.rbclassItemi

随机推荐