【问题标题】:Recyclerview in fragment. Not updating after Activity has been closed片段中的回收站视图。 Activity 关闭后不更新
【发布时间】:2019-12-13 18:21:00
【问题描述】:

我正在使用具有三个选项卡(三个片段)的视图寻呼机。在其中一个片段中,我有一个回收者视图。此回收站视图中的项目每 2 秒从网络更新一次。当我第一次启动应用程序时,回收器视图运行得很好。即使导航到不同的选项卡或使用主页按钮导航出我的应用程序,一切正常。

但是,当我使用返回键关闭应用程序然后再次进入我的应用程序时,回收站视图不再更新。它显示应用退出时的状态。我通过控制台监控适配器,它继续使用正确的数据,只有回收站视图没有显示。我尝试了各种方法来“重新连接”适配器和回收器视图,但它不起作用。我有这个问题好几天了。知道这个问题的原因吗?请参阅相关代码进行故障排除。谢谢!

public class UserAreaFragment extends Fragment implements PopupMenu.OnMenuItemClickListener {

   private RecyclerView mRecyclerview;
   private UserAdapter mAdapter;
   private RecyclerView.LayoutManager mLayoutmanager;
   private Handler mainHandler = new Handler();



   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle      savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_user_area, container, false);

        ...

        mAdapter = new UserAdapter(getActivity(), UserDataSingleton.getUserList());
        mRecyclerview = root.findViewById(R.id.userListing);
        mRecyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
        mRecyclerview.setAdapter(mAdapter);

        mAdapter.setOnItemClickListener(new UserAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {

                ...

            }

        });


   }


//Somewhere in my method that receives the data from an online DB:

         UserDataSingleton.getUserList().clear();
         UserDataSingleton.getUserList().addAll(serverResponse);
         mainHandler.post(updateUi);


//And finally the updateUi method: this is essential just sorting and then notifydatasetchanged

Runnable updateUi = new Runnable() {
        @Override
        public void run() {

           Collections.sort(UserDataSingleton.getUserList(), new Comparator<UserItem>() {
            @Override
            public int compare(UserItem lhs, UserItem rhs) {
                // -1 - less than, 1 - greater than, 0 - equal, all inversed for descending
                return Double.parseDouble(lhs.getmDistance()) > Double.parseDouble(rhs.getmDistance()) ? 1 : Double.parseDouble(lhs.getmDistance()) < Double.parseDouble(rhs.getmDistance()) ? -1 : 0;
            }
        });

        mAdapter.notifyDataSetChanged();

        }
    };



//and this is my Adapter:

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {
    private UserAdapter.OnItemClickListener mListener;
    private Context mContext;
    private List<UserItem> mUserlist;

    public UserAdapter(Context context,List<UserItem> userList){
        mUserlist=userList;
        mContext = context;
    }


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

    public void setOnItemClickListener(UserAdapter.OnItemClickListener listener) {
        this.mListener = listener;
    }




    public static class UserViewHolder extends RecyclerView.ViewHolder{
        public TextView mUsername;
        public TextView mDistance;

        public ImageView userIcon;
        public UserViewHolder(@NonNull View itemView, final UserAdapter.OnItemClickListener listener) {
            super(itemView);
            mUsername = itemView.findViewById(R.id.tvNearUsername);
            mDistance = itemView.findViewById(R.id.tvDistance);
            userIcon = itemView.findViewById(R.id.usericon);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listener != null){
                        int position = getAdapterPosition();
                        if (position!= RecyclerView.NO_POSITION){
                            listener.onItemClick(position);
                        }
                    }
                }
            });
        }

    }


    @NonNull
    @Override
    public UserAdapter.UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View v= inflater.inflate(R.layout.user_item, parent, false);
        UserViewHolder uvh= new UserViewHolder(v,mListener);
        return uvh;
    }

    @Override
    public void onBindViewHolder(@NonNull UserAdapter.UserViewHolder holder, int position) {
        UserItem currentitem = mUserlist.get(position);

        holder.mUsername.setText(currentitem.getmNearUsername());
        if (currentitem.isArea()){
            holder.mDistance.setVisibility(View.INVISIBLE);
            holder.userIcon.setImageResource(R.drawable.ic_placeicon);

        }else{
            holder.mDistance.setVisibility(View.VISIBLE);
        }
        int distToNextTen = ((Integer.parseInt(currentitem.getmDistance())+5)/10)*10+10;
        holder.mDistance.setText("< "+distToNextTen+"m");
    }

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




}

我试图只显示影响问题的行以提高可读性。如果您需要查看更多代码,请告诉我。感谢这个伟大的社区!

(我认为问题可能与主处理程序没有指向正确的视图有关,或者可能是适配器-recyclerview 连接的问题,但我已经尝试了很多方法,但找不到解决方案)

【问题讨论】:

  • "....它继续使用正确的数据,只有回收站视图没有显示这个"。你的意思是网络调用正在发生并且更新的数据被注入到适配器中?
  • 是的。例如,当我通过控制台检查适配器的计数时,它是正确的。但是回收站视图显示不同。
  • 看看这个。由于您正在使用 Handler 发布更新,并且在返回(暂停)状态时出现问题,这可能是相关的:stackoverflow.com/questions/8040280/…
  • 谢谢,但我认为这是一个不同的问题。重新启动应用程序后,我的处理程序线程也运行良好。 updateUi 正在运行,适配器被注入了正确的数据,只有回收器视图似乎并不关心。我的解决方法曾经是放置“System.exit(0);”在父活动 onDestroy。因此,该应用程序被 100% 杀死,并且在重新启动时一切正常。但这会导致其他领域出现更多问题,并不是一个非常优雅的解决方案。

标签: java android android-fragments android-recyclerview


【解决方案1】:

好的,我发现了问题。它与未在 onCreate 中声明的可运行对象和处理程序有关。不知怎的,这搞砸了。我对我的代码进行了重大重构以解决它,因此很难确定究竟是哪一行出现了问题,但如果您遇到类似的问题,请检查您的 runOnUi 和处理程序声明是否发生在正确的位置。

【讨论】:

    猜你喜欢
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多