Recycler View - 自定义复选框:滚动时保持状态

时间:2016-07-10 12:56:37

标签: android android-fragments android-recyclerview adapter

我已经看过很多关于这个"问题的帖子"使用RecyclerView,但我无法修复它。

每次滚动时,我的自定义CheckBoxes(starStyle)都会一直打开/关闭。 我已经尝试在Stack上关注其他解决方案,但似乎没有人为我做这个工作。

为了解释我的应用程序的结构,我有一个很长的列表(每个项目都有一个StarStyle CheckBox):当我点击一个项目时,该应用程序将我带入该项目的详细信息页面,我在那里也可以设置CheckBox。我设法绑定列表的复选框和详细信息页面中的复选框,但我仍然遇到这个恼人的问题。

这是 ListFragment 的代码:

公共类PetrolStationListFragment扩展了Fragment {

    private RecyclerView mPetrolStationRecyclerView;
    private PetrolStationAdapter mAdapter;

    private int itemPosition;
    private int mLastAdapterClickPosition = -1;
    private List<Boolean> mCheckState = new ArrayList<>();

    public static boolean toBeCreated;

    private static final String ARG_POSITION = "position";


    // Design pattern to instantiate a new fragment.
    public static PetrolStationListFragment newInstance(int position) {
        PetrolStationListFragment fragment = new PetrolStationListFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_POSITION, position);

        fragment.setArguments(args);

        return fragment;
    }


    /********************************************************/

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_petrol_station_list, container, false);

        mPetrolStationRecyclerView = (RecyclerView) view.findViewById(R.id.petrol_recycler_view);
        mPetrolStationRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        updateUI();

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();

        updateUI();
    }

    private void updateUI() {
        PetrolStationDAO petrolStationDAO = PetrolStationDAO.get(getActivity());
        List<PetrolStation> petrolStations = petrolStationDAO.getPetrolStations();

        if (mAdapter == null || toBeCreated) {
            mAdapter = new PetrolStationAdapter(petrolStations);
            mPetrolStationRecyclerView.setAdapter(mAdapter);
            toBeCreated = false;
        } else {
            if (mLastAdapterClickPosition < 0) {
                mAdapter.setPetrolStations(petrolStations);
                mAdapter.notifyDataSetChanged();
            } else {
                mAdapter.notifyItemChanged(mLastAdapterClickPosition);
                mLastAdapterClickPosition = -1;
            }

            mAdapter.notifyItemChanged(itemPosition);
        }
    }

    private class PetrolStationHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private PetrolStation mPetrolStation;

        private TextView mNameTextView;
        private TextView mAddressTextView;
        private TextView mDistanceTextView;
        private CheckBox mCheckBox;
        private int mPosition;

        public PetrolStationHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);

            mNameTextView = (TextView) itemView.findViewById(R.id.list_item_station_name_text_view);
            mAddressTextView = (TextView) itemView.findViewById(R.id.list_item_station_address_text_view);
            mDistanceTextView = (TextView) itemView.findViewById(R.id.list_item_station_distance_text_view);
            mCheckBox = (CheckBox) itemView.findViewById(R.id.checkbox);
        }

        public void bindPetrolStation(PetrolStation petrolStation, int position) {
            mPetrolStation = petrolStation;
            mNameTextView.setText(mPetrolStation.getName());
            mAddressTextView.setText("Via Verdi, 19/A");
            mDistanceTextView.setText("300 meters");

            mPosition = position;
            //mCheckBox.setChecked(mPetrolStation.isFavourite());
            mCheckBox.setChecked(mCheckState.get(mPosition));
            Log.d("BIND_POSITION", "position: " + mPosition + " / status: " + mCheckState.get(mPosition));

            mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    boolean boxChecked = mPetrolStation.isFavourite();
                    Log.d("BOX_CHECKED_POSITION", "boxChecked: " + boxChecked);

                    if (boxChecked) {
                        mPetrolStation.setFavourite(false);
                    } else {
                        mPetrolStation.setFavourite(true);
                    }

                    if (boxChecked) {
                        mCheckState.set(mPosition, false);
                    } else {
                        mCheckState.set(mPosition, true);
                    }

                    Log.d("CHECK_POSITION", "mCheckState: " + mCheckState);

                    // TODO: DB connection.
//                    PetrolStationDAO.get(getActivity()).updateItem(mCrime);
                }
            });
        }

        @Override
        public void onClick(View v) {
            itemPosition = mPetrolStationRecyclerView.getChildAdapterPosition(v);
            Intent intent = PetrolStationPagerActivity.newIntent(getActivity(), mPetrolStation.getId());
            startActivity(intent);
        }

    }

    private class PetrolStationAdapter extends RecyclerView.Adapter<PetrolStationHolder> {

        private List<PetrolStation> mPetrolStations;

        public PetrolStationAdapter(List<PetrolStation> petrolStations) {
            mPetrolStations = petrolStations;

            for (int i = 0; i < mPetrolStations.size(); i++) {
                mCheckState.add(false);
            }
        }

        @Override
        public PetrolStationHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
            View view = layoutInflater.inflate(R.layout.list_item_petrol_station, parent, false);

            return new PetrolStationHolder(view);
        }

        @Override
        public void onBindViewHolder(PetrolStationHolder holder, int position) {
            PetrolStation petrolStation = mPetrolStations.get(position);
            holder.bindPetrolStation(petrolStation, position);
//            holder.setIsRecyclable(false);
        }

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

        public void setPetrolStations(List<PetrolStation> petrolStations) {
            mPetrolStations = petrolStations;
        }

    }

}

这是 DetailsFragment

的一个
public class PetrolStationFragment extends Fragment {

    private static final String ARG_PETROL_STATION_ID = "petrol_station_id";

    private PetrolStation mPetrolStation;
    private TextView mInfo;
    private CheckBox mCheckBox;

    private static TabLayout mTabLayout;
    private static ViewPager mViewPager;
    private static int intItems = 2;

    // Navigation Tab constants.
    private static final int SELF_SERVICE_POSITION = 0;
    private static final int FULL_SERVICE_POSITION = 1;


    // Design pattern to instantiate a new fragment.
    public static PetrolStationFragment newInstance(long petrolStationId) {
        Bundle args = new Bundle();
        args.putLong(ARG_PETROL_STATION_ID, petrolStationId);

        PetrolStationFragment fragment = new PetrolStationFragment();
        fragment.setArguments(args);

        return fragment;
    }


    /********************************************************/

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        long mId = getArguments().getLong(ARG_PETROL_STATION_ID);
        mPetrolStation = PetrolStationDAO.get(getActivity()).getPetrolStation(mId);
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceStace) {
        View view = inflater.inflate(R.layout.fragment_petrol_station, container, false);

        mInfo = (TextView) view.findViewById(R.id.petrol_station);
        mCheckBox = (CheckBox) view.findViewById(R.id.checkbox);

        mInfo.setText(mPetrolStation.getName());
        mCheckBox.setChecked(mPetrolStation.isFavourite());

        // TODO: to fix.
        mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isFavourite) {
                mPetrolStation.setFavourite(isFavourite);
            }
        });

        // Setup Views.
        mTabLayout = (TabLayout) view.findViewById(R.id.pager_header);
        mViewPager = (ViewPager) view.findViewById(R.id.pager);

        // Set an Adapter for the View Pager.
        TabPagerAdapter tabPagerAdapter = new TabPagerAdapter(getChildFragmentManager());
        mViewPager.setAdapter(tabPagerAdapter);
        mTabLayout.setupWithViewPager(mViewPager);

        mViewPager.setCurrentItem(SELF_SERVICE_POSITION);

        mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {

            int flag;

            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                mViewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }

        });

        mInfo.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                mPetrolStation.setName(charSequence.toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

        return view;
    }

    class TabPagerAdapter extends FragmentPagerAdapter {
        public TabPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        // Return fragment with respect to position.
        @Override
        public Fragment getItem(int position) {
            Fragment fragment;

            switch (position) {

                case SELF_SERVICE_POSITION: {
                    fragment = SelfServiceFragment.newInstance();

                    return fragment;
                }

                case FULL_SERVICE_POSITION: {
                    fragment = FullServiceFragment.newInstance();

                    return fragment;
                }

            }

            return null;
        }

        @Override
        public int getCount() {
            return intItems;
        }

        // This method returns the title of the tab according to its position.
        @Override
        public CharSequence getPageTitle(int position) {

            switch (position) {

                case SELF_SERVICE_POSITION: {
                    String mSelfService = getResources().getString(R.string.self_service);

                    return mSelfService;
                }

                case FULL_SERVICE_POSITION: {
                    String mFullService = getResources().getString(R.string.full_service);

                    return mFullService;
                }

            }

            return null;

        }

    }

}

有关如何解决此问题的任何提示? 我错过了某种检查吗?

1 个答案:

答案 0 :(得分:1)

// utils.js
export default {
  textFormat(args) {
    var s = args[0];
    for (var i = 0; i < args.length - 1; i++) {
      var reg = new RegExp("\\{" + i + "\\}", "gm");
      s = s.replace(reg, args[i + 1]);
    }
    return s;
  }
}