使用CustomViewHolder

时间:2017-12-07 12:24:33

标签: java android recycler-adapter

我想要做的是,我有一个适配器,我用于许多不同的活动,每个活动都有自己的ViewHolder。所以我首先在没有ViewHolder的情况下制作一个名为DimRecyclerAbstractAdapter的抽象回收器适配器。然后,对于每个不同的活动,我正在创建一个名为DimCustomAdapter的静态内部类,它扩展了DimRecyclerAbstractAdapter,拥有它自己的ViewHolder。但是我收到了这个错误。

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
                                                                                     at java.util.ArrayList.get(ArrayList.java:411)

这是抽象适配器类 -

public abstract class DimRecyclerAbstractAdapter<VHA extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VHA> {

    private List<tbl_dim_1> mtbldimList1;

    public DimRecyclerAbstractAdapter(List<tbl_dim_1> tblDimList1) {
        this.mtbldimList1 = tblDimList1;
    }


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

    public void addItems(List<tbl_dim_1> tblDimList1) {

        this.mtbldimList1 = tblDimList1;
        notifyDataSetChanged();
    }

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

}

这是我实现自定义ViewHolder的活动 -

public class DetailActivity1 extends LifecycleActivity{

    DimListViewModel dmvmodel;
    RecyclerView rcView;
    DimCustomAdapter rcAdapter;
    public static final String LOG_TAG = "In DetailActivity1 ";


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.recycler_view);

        Intent receivedIntent = getIntent();
        int rid_int = receivedIntent.getIntExtra("mRId",0);
        Log.v(LOG_TAG,"Rid value int == " + rid_int);

        rcView = (RecyclerView) findViewById(R.id.recyclerView);

        rcAdapter = new DimCustomAdapter(new ArrayList<tbl_dim_1>());
        rcView.setLayoutManager(new LinearLayoutManager(DetailActivity1.this));
        Log.v(LOG_TAG, "Layout manager set");
        rcView.setAdapter(rcAdapter);

        dmvmodel = ViewModelProviders.of(this).get(DimListViewModel.class);
        Log.v(LOG_TAG, "View model returned");


        dmvmodel.getDimList2con1(rid_int).observe(DetailActivity1.this, new Observer<List<tbl_dim_1>>() {

            @Override
            public void onChanged(@Nullable List<tbl_dim_1> changedItems) {
                Log.v(LOG_TAG, "onChanged called, items will be added");
                rcAdapter.addItems(changedItems);
            }
        });
    }

    @Override
    protected void onDestroy() {

        rcAdapter = null;
        rcView.setAdapter(null);
        rcView.setLayoutManager(null);
        rcView = null;
        dmvmodel = null;
        super.onDestroy();
        RefWatcher refWatcher = LeakCheckApplication.getRefWatcher(this);
        refWatcher.watch(this);
    }

    public static class DimCustomAdapter extends DimRecyclerAbstractAdapter<DimCustomAdapter.RecyclerViewHolder> {

        private static List<tbl_dim_1> mtbldimCustom;

        DimCustomAdapter(List<tbl_dim_1> tblDimListPassed) {
            super(mtbldimCustom);
            mtbldimCustom = tblDimListPassed;
        }

        @Override
        public DimCustomAdapter.RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View vw = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.recycler_item, parent, false);

//          vw.setOnClickListener(vwOnClickListener);
            return new DimCustomAdapter.RecyclerViewHolder(vw);
        }

        @Override
        public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
//          Log.v(LOG_TAG, "Inside onBindViewHolder - ");
            if (holder.dataTextView.getText() != null) {
                String LOG_TAG = "DimCustomAdapter:";
                Log.d(LOG_TAG, "holder is not null, i was right");
                holder.dataTextView.setText(null);
                holder.dataTextView.setOnClickListener(null);
            }

            final tbl_dim_1 dimAtPosition = mtbldimCustom.get(position);
            holder.dataTextView.setText(dimAtPosition.mCONTENT);
            holder.dataTextView.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View arg) {

                    Intent dw = new Intent(arg.getContext(), DetailActivity2.class);
                    dw.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    dw.putExtra("mRId", dimAtPosition.mR_ID);
                    arg.getContext().startActivity(dw);
                }
            });
        }

        class RecyclerViewHolder extends RecyclerView.ViewHolder {
            private TextView dataTextView;

            RecyclerViewHolder(View view) {
                super(view);
                dataTextView = (TextView) view.findViewById(R.id.data_text_view);
            }
        }
    }
}

这就是我在同一个活动中从外部类调用这个内部类的方法 -

DimCustomAdapter rcAdapter = new DimCustomAdapter(new ArrayList<tbl_dim_1>());

2 个答案:

答案 0 :(得分:1)

它是因为您在创建适配器时传递的空列表。 DimCustomAdapter rcAdapter = new DimCustomAdapter(new ArrayList<tbl_dim_1>());

在调用

之前,只需在onBindViewHolder方法中添加空或空检查
final tbl_dim_1 dimAtPosition = mtbldimCustom.get(position);

希望这会停止崩溃您的应用程序。

您可以尝试如下,

ArrayList<tbl_dim_1> list = new ArrayList<>()
rcAdapter = new DimCustomAdapter(list);

然后在观察方法中,

dmvmodel.getDimList2con1(rid_int).observe(DetailActivity1.this, new Observer<List<tbl_dim_1>>() {

            @Override
            public void onChanged(@Nullable List<tbl_dim_1> changedItems) {
                Log.v(LOG_TAG, "onChanged called, items will be added");
                list.addAll(changedItems);
                rcAdapter.notifyDataSetChanged()
            }
        });

答案 1 :(得分:0)

这是我为我的问题解决的解决方案(如果有人遇到同样的问题)。 困扰杜尔加的回答 -

  1. 首先,我添加了他在评论中提到的isEmpty()检查。
  2. 然后在活动中我将代码更改为此 -
  3. a)在DimCustomAdapter中添加了这个新方法 -

    public void changeList(List<tbl_dim_1> addedList){
                mtbldimCustom = addedList;
            }
    

    b)在观察方法中调用此方法 -

    dmvmodel.getDimList2con1(rid_int).observe(DetailActivity1.this, new Observer<List<tbl_dim_1>>() {
    
                @Override
                public void onChanged(@Nullable List<tbl_dim_1> changedItems) {
                    Log.v(LOG_TAG, "onChanged called, items will be added");
                    rcAdapter.changeList(changedItems);
                    rcAdapter.addItems(changedItems);
                }
            });