タブレット用プログラムの書き止め

android OS & iPadOS の記録。

RecyclerView【と】AsyncTask

2022-11-16 17:02:43 | Android studio 日記

ViewModel に recyclerView_id を管理させ、RecyclerView アダプタがアタッチ、デタッチされたとき recyclerView_id を変化させる。
アダプターが変化しなければ、recyclerView_id も変化しない。
ワーカースレッドで recyclerView_id を比較して更新の可否を決める。

意外とシンプルに判断できる。


public class MainViewModel extends ViewModel {

    private MutableLiveData< RecyclerView> recyclerView = null;
    public MutableLiveData< RecyclerView> getRecyclerView() {
        if ( recyclerView == null ) {
            recyclerView = new MutableLiveData< RecyclerView>(null);
            recyclerView_id = 0;
        }
        return recyclerView;
    }
    public RecyclerView getValueRecyclerView() {
        return getRecyclerView().getValue();
    }
    private long recyclerView_id;
    public void setRecyclerView(RecyclerView rv) {
        getRecyclerView().setValue(rv);
        recyclerView_id++;
    }
    public void clearRecyclerView() {

        if ( getRecyclerView() != null && getRecyclerView().getValue() != null ) {
            getRecyclerView().getValue().setAdapter(null);

            getRecyclerView().setValue(null);
            recyclerView_id++;
        }
    }
    public long getValueRecyclerViewID() {
        return recyclerView_id;
    }

    //省略
}

 


public class MyAdapter extends RecyclerView.Adapter {

    private final MainViewModel mViewModel;
    private RecyclerView myRecyclerView = null;
    private View.OnClickListener myListener;

    //省略

    public MyAdapter(MainViewModel viewModel, View.OnClickListener listener) {
        mViewModel = viewModel;
        myListener = listener;
        //省略
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        myRecyclerView = recyclerView;
        mViewModel.setRecyclerView(myRecyclerView);//****
    }

    @Override
    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
        myRecyclerView = null;
        mViewModel.setRecyclerView(null);//****
        super.onDetachedFromRecyclerView(recyclerView);
    }

    //省略

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        if (getItemCount() <= 0) return;

        Bitmap bitmap = loadImage(myImageAbsPaths.get(position));
        if (bitmap != null)
            holder.imageView.setImageBitmap(bitmap);
        else {
            holder.imageView.setImageBitmap(
                      BitmapFactory.decodeResource(mMainModel.getContext().getResources(), R.drawable.img_file));
            MyAsyncTask2 mAsyncTask = new MyAsyncTask2(mViewModel, myRecyclerView, position);
            mAsyncTask.execute(myImageAbsPaths.get(position));
        }

        holder.textView.setText(String.valueOf(position + 1));
        initStartPositionOffset(holder.linearLayout, position);
        holder.linearLayout.setId(holder.getAdapterPosition());
        holder.linearLayout.setOnClickListener(myListener);
    }

    //省略
}

 


public class MyAsyncTask2 {

    private MainViewModel mViewModel;
    private RecyclerView mRecyclerView;
    private final int vID;

    private long mRecyclerView_id = 0;


    //省略

    public MyAsyncTask2(MainViewModel data, RecyclerView rv, int id ) {
        super();

        mViewModel = data;
        mRecyclerView = rv ;
        vID = id;
        mRecyclerView_id = data.getValueRecyclerViewID();

        //省略
    }

    private class TaskRunnable implements Runnable {

        private String targetPath = "";
        public TaskRunnable(String param) { targetPath = param; }

        @Override
        public void run() {
            
            //省略

            new Handler(Looper.getMainLooper())
                    .post(() -> onPostExecute(result));
        }
    }

    public void execute(String param) {
        mViewModel.getValueExecutorService().submit(new TaskRunnable(param));// ワーカースレッド実行
    }

    void onPostExecute(int result) {

        if ( mRecyclerView == null || mRecyclerView_id != mViewModel.getValueRecyclerViewID() ) {
            finish();
            return;
        }

        switch ( result ) {
            case 0:
                if ( vID < mRecyclerView.getAdapter().getItemCount() ) {
                        mRecyclerView.getAdapter().notifyItemChanged(vID);
                }
                break;
            
            //省略
        }
        finish();
    }
    void finish() {
        mRecyclerView = null;
        mViewModel = null;
    }

    //省略
}