试着学习如何在RecyclerView中使用getItemViewType()

时间:2017-10-11 23:10:22

标签: android android-recyclerview

所以,在有人责备我问一个已经问过的问题之前,我已经在这个网站上找到了一个关于如何使用方法getItemViewType()在RecyclerView中呈现不同listItem的解决方案。我正在尝试了解它是如何工作的,因为我甚至看到了RecyclerView实现本身的变体,但这是我的问题。在我的onBindViewHolder方法中,它无法识别我创建的每个预期ViewHolders中的bind()方法。有人可以告诉我为什么吗?

public class CrimeListFragment extends Fragment {

    private static final int ITEM_TYPE_NORMAL = 0;
    private static final int ITEM_TYPE_COPS = 1;

    private RecyclerView mCrimeRecyclerView;
    private CrimeAdapter mAdapter;



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

        mCrimeRecyclerView = (RecyclerView) view
                .findViewById(R.id.crime_recycler_view);
        mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        updateUI();

        return view;
    }

    private void updateUI() {
        CrimeLab crimeLab = CrimeLab.get(getActivity());
        List<Crime> crimes = crimeLab.getCrimes();

        mAdapter = new CrimeAdapter(crimes);
        mCrimeRecyclerView.setAdapter(mAdapter);
    }



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

        private Crime mCrime;

        private TextView mTitleTextView;
        private TextView mDateTextView;

        public CrimeHolder(LayoutInflater inflater, ViewGroup parent) {
            super(inflater.inflate(R.layout.list_item_crime, parent, false));
            itemView.setOnClickListener(this);

            mTitleTextView = (TextView) itemView.findViewById(R.id.crime_title);
            mDateTextView = (TextView) itemView.findViewById(R.id.crime_date);
        }

        public void bind(Crime crime) {
            mCrime = crime;
            mTitleTextView.setText(mCrime.getTitle());
            mDateTextView.setText(mCrime.getDate().toString());
        }

        @Override
        public void onClick(View view) {
            Toast.makeText(getActivity(),
                    mCrime.getTitle() + " clicked!", Toast.LENGTH_SHORT)
                    .show();
        }
    }

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

        private Crime mCrime;

        private TextView mTitleTextView;
        private TextView mDateTextView;
        private Button mPoliceButton;

        public PoliceHolder(LayoutInflater inflater, ViewGroup parent){
            super(inflater.inflate(R.layout.list_item_crime_police, parent, false));
            itemView.setOnClickListener(this);

            mTitleTextView = (TextView)itemView.findViewById(R.id.crime_title);
            mDateTextView = (TextView)itemView.findViewById(R.id.crime_date);
            mPoliceButton = (Button)itemView.findViewById(R.id.police_button);
            mPoliceButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(getActivity(), "call the police!", Toast.LENGTH_SHORT).show();
                }
            });
        }

        public void bind(Crime crime){
            mCrime = crime;
            mTitleTextView.setText(mCrime.getTitle());
            mDateTextView.setText(mCrime.getDate().toString());
        }

        @Override
        public void onClick(View view){
            Toast.makeText(getActivity(), mCrime.getTitle() + "Clicked!", Toast.LENGTH_SHORT).show();
        }


    }


    private class CrimeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        private List<Crime> mCrimes;

        public CrimeAdapter(List<Crime> crimes) {
            mCrimes = crimes;
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater = LayoutInflater.from(getActivity());

            if(viewType == ITEM_TYPE_COPS){
                return new PoliceHolder(layoutInflater, parent);
            }
            if (viewType == ITEM_TYPE_NORMAL) {
                return new CrimeHolder(layoutInflater, parent);
            }

            return null;
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            Crime crime = mCrimes.get(position);
            final int itemType = getItemViewType(position);

            if(itemType == ITEM_TYPE_COPS){
                (PoliceHolder)holder.bind(crime);
            }
            if(itemType == ITEM_TYPE_NORMAL){
                (CrimeHolder)holder.bind(crime);
            }

        }

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

        @Override
        public int getItemViewType(int position){
            if (mCrimes.get(position).isRequiresPolice()){
                return ITEM_TYPE_COPS;
            } else {
                return ITEM_TYPE_NORMAL;
            }
        }

    }
}

3 个答案:

答案 0 :(得分:1)

问题是您没有正确地将ViewHolder强制转换为您创建的类。您的方法应如下所示:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    Crime crime = mCrimes.get(position);
    final int itemType = getItemViewType(position);

    if(itemType == ITEM_TYPE_COPS){
        ((PoliceHolder)holder).bind(crime);
    }
    if(itemType == ITEM_TYPE_NORMAL){
        ((CrimeHolder)holder).bind(crime);
    }
}

答案 1 :(得分:0)

在onBindViewHolder()中调用bind()方法时,尝试添加一组额外的括号,以确保编译器理解您正在转换holder对象而不是bind()方法的结果:

if(itemType == ITEM_TYPE_COPS){
    ((PoliceHolder)holder).bind(crime);
}
if(itemType == ITEM_TYPE_NORMAL){
    ((CrimeHolder)holder).bind(crime);
}

答案 2 :(得分:0)

你正在向持枪人(犯罪)的警察投票,但你不会那样。您想将持有者强制转换为PoliceHolder,然后访问方法绑定。为此你应该这样做:

((PoliceHolder)holder).bind(crime);

希望它有效。