Can't update RecyclerView from my model class?

I am working on a RecyclerView, which should be Draggable and swipeable. Everything works perfectly.

The data is retrieved in the same class with the name ExerciseDataProvider, and the RV code is another piece RecyclerListViewFragment.

The problem is that I cannot notify Data changed from FetchExercisein the postExecute method. Thus, the data is not populated in the RV.

Please guide me in the right direction.

ACTIVITY

    public class DraggableSwipeableExampleActivity extends AppCompatActivity {
        private static final String FRAGMENT_TAG_DATA_PROVIDER = "data provider";
        private static final String FRAGMENT_LIST_VIEW = "list view";
        private static final String FRAGMENT_TAG_ITEM_PINNED_DIALOG = "item pinned dialog";

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_demo);

            if (savedInstanceState == null) {
                getSupportFragmentManager().beginTransaction()
                        .add(new ExampleDataProviderFragment(), FRAGMENT_TAG_DATA_PROVIDER)
                        .commit();
                getSupportFragmentManager().beginTransaction()
                        .add(R.id.container, new RecyclerListViewFragment(), FRAGMENT_LIST_VIEW)
                        .commit();
            }
        }

 public AbstractDataProvider getDataProvider() {
        final Fragment fragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_DATA_PROVIDER);
        return ((ExampleDataProviderFragment) fragment).getDataProvider();
    }

DATA PROVIDER

public class ExerciseDataProvider extends AbstractDataProvider {
    private List<ConcreteData> mData;
    private ConcreteData mLastRemovedData;
    private int mLastRemovedPosition = -1;

    public ExerciseDataProvider() {
        new FetchExercise().execute();
        mData = new LinkedList<>();
    }

    class FetchExercise extends AsyncTask<Void,Void,Void> {

        @Override
        protected Void doInBackground(Void... params) {
            final int viewType = 0;
            final int swipeReaction = RecyclerViewSwipeManager.REACTION_CAN_SWIPE_UP | RecyclerViewSwipeManager.REACTION_CAN_SWIPE_DOWN;

            String url = "https://gist.githubusercontent.com/fake/cb9aa5494e7ee36ac3ca/raw/a4abfd19368063/exercise.JSON";
            Log.d("Path", url);
            try {
                OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder().url(url).build();
                Response response = client.newCall(request).execute();
                String jsonData = response.body().string();
                try {
                    JSONArray jsonArray = new JSONArray(jsonData);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        final long id = i;
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        String exercise_name = jsonObject.getString("name");
                        int exercise_duration = jsonObject.getInt("duration");

                        mData.add(new ConcreteData(id, viewType, exercise_name, exercise_duration, swipeReaction));
                        Log.d("exercise_name", exercise_name);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
        }
    }


    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Data getItem(int index) {
        if (index < 0 || index >= getCount()) {
            throw new IndexOutOfBoundsException("index = " + index);
        }

        return mData.get(index);
    }

    @Override
    public int undoLastRemoval() {
        if (mLastRemovedData != null) {
            int insertedPosition;
            if (mLastRemovedPosition >= 0 && mLastRemovedPosition < mData.size()) {
                insertedPosition = mLastRemovedPosition;
            } else {
                insertedPosition = mData.size();
            }

            mData.add(insertedPosition, mLastRemovedData);

            mLastRemovedData = null;
            mLastRemovedPosition = -1;

            return insertedPosition;
        } else {
            return -1;
        }
    }

    @Override
    public void moveItem(int fromPosition, int toPosition) {
        if (fromPosition == toPosition) {
            return;
        }

        final ConcreteData item = mData.remove(fromPosition);
        mData.add(toPosition, item);
        mLastRemovedPosition = -1;
    }

    @Override
    public void removeItem(int position) {
        //noinspection UnnecessaryLocalVariable
        final ConcreteData removedItem = mData.remove(position);

        mLastRemovedData = removedItem;
        mLastRemovedPosition = position;
    }

    public static final class ConcreteData extends Data {

        private final long mId;
        private final String mText;
        private final int mViewType;
        private final int mDuration;
        private boolean mPinned;

        ConcreteData(long id, int viewType, String text, int duration, int swipeReaction) {
            mId = id;
            mViewType = viewType;
            mText = text;
            mDuration = duration;
        }

        @Override
        public int getViewType() {
            return mViewType;
        }

        @Override
        public int getDuration() {
            return mDuration;
        }

        @Override
        public long getId() {
            return mId;
        }

        @Override
        public String toString() {
            return mText;
        }

        @Override
        public String getText() {
            return mText;
        }

        @Override
        public boolean isPinned() {
            return mPinned;
        }

        @Override
        public void setPinned(boolean pinned) {
            mPinned = pinned;
        }

    }
}

RecyclerListViewFragment

public class RecyclerListViewFragment extends Fragment {
    private RecyclerView mRecyclerView;
    private RecyclerView.LayoutManager mLayoutManager;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.Adapter mWrappedAdapter;
    private RecyclerViewDragDropManager mRecyclerViewDragDropManager;
    private RecyclerViewSwipeManager mRecyclerViewSwipeManager;
    private RecyclerViewTouchActionGuardManager mRecyclerViewTouchActionGuardManager;

    public RecyclerListViewFragment() {
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_recycler_list_view, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //noinspection ConstantConditions
        mRecyclerView = (RecyclerView) getView().findViewById(R.id.recycler_view);
        mLayoutManager = new LinearLayoutManager(getContext());

        // touch guard manager  (this class is required to suppress scrolling while swipe-dismiss animation is running)
        mRecyclerViewTouchActionGuardManager = new RecyclerViewTouchActionGuardManager();
        mRecyclerViewTouchActionGuardManager.setInterceptVerticalScrollingWhileAnimationRunning(true);
        mRecyclerViewTouchActionGuardManager.setEnabled(true);

        // drag & drop manager
        mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();
        mRecyclerViewDragDropManager.setDraggingItemShadowDrawable(
                (NinePatchDrawable) ContextCompat.getDrawable(getContext(), R.drawable.material_shadow_z3));

        // swipe manager
        mRecyclerViewSwipeManager = new RecyclerViewSwipeManager();

        //adapter
        final MyDraggableSwipeableItemAdapter myItemAdapter = new MyDraggableSwipeableItemAdapter(getDataProvider());
        myItemAdapter.setEventListener(new MyDraggableSwipeableItemAdapter.EventListener() {
            @Override
            public void onItemRemoved(int position) {
                ((DraggableSwipeableExampleActivity) getActivity()).onItemRemoved(position);
            }

            @Override
            public void onItemViewClicked(View v, boolean pinned) {
                onItemViewClick(v, pinned);
            }
        });

        mAdapter = myItemAdapter;

        mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(myItemAdapter);      // wrap for dragging
        mWrappedAdapter = mRecyclerViewSwipeManager.createWrappedAdapter(mWrappedAdapter);      // wrap for swiping

        final GeneralItemAnimator animator = new SwipeDismissItemAnimator();
        animator.setSupportsChangeAnimations(false);

        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setAdapter(mWrappedAdapter);  // requires *wrapped* adapter
        mRecyclerView.setItemAnimator(animator);

        // additional decorations
        //noinspection StatementWithEmptyBody
        if (supportsViewElevation()) {
            // Lollipop or later has native drop shadow feature. ItemShadowDecorator is not required.
        } else {
            mRecyclerView.addItemDecoration(new ItemShadowDecorator((NinePatchDrawable) ContextCompat.getDrawable(getContext(), R.drawable.material_shadow_z1)));
        }
        mRecyclerView.addItemDecoration(new SimpleListDividerDecorator(ContextCompat.getDrawable(getContext(), R.drawable.list_divider_h), true));
        mRecyclerViewTouchActionGuardManager.attachRecyclerView(mRecyclerView);
        mRecyclerViewSwipeManager.attachRecyclerView(mRecyclerView);
        mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView);
    }

    @Override
    public void onPause() {
        mRecyclerViewDragDropManager.cancelDrag();
        super.onPause();
    }

    @Override
    public void onDestroyView() {
        if (mRecyclerViewDragDropManager != null) {
            mRecyclerViewDragDropManager.release();
            mRecyclerViewDragDropManager = null;
        }

        if (mRecyclerViewSwipeManager != null) {
            mRecyclerViewSwipeManager.release();
            mRecyclerViewSwipeManager = null;
        }

        if (mRecyclerViewTouchActionGuardManager != null) {
            mRecyclerViewTouchActionGuardManager.release();
            mRecyclerViewTouchActionGuardManager = null;
        }

        if (mRecyclerView != null) {
            mRecyclerView.setItemAnimator(null);
            mRecyclerView.setAdapter(null);
            mRecyclerView = null;
        }

        if (mWrappedAdapter != null) {
            WrapperAdapterUtils.releaseAll(mWrappedAdapter);
            mWrappedAdapter = null;
        }
        mAdapter = null;
        mLayoutManager = null;

        super.onDestroyView();
    }

    private void onItemViewClick(View v, boolean pinned) {
        int position = mRecyclerView.getChildAdapterPosition(v);
        if (position != RecyclerView.NO_POSITION) {
            ((DraggableSwipeableExampleActivity) getActivity()).onItemClicked(position);
        }
    }

    public AbstractDataProvider getDataProvider() {
        return ((DraggableSwipeableExampleActivity) getActivity()).getDataProvider();
    }

    public void notifyItemChanged(int position) {
        mAdapter.notifyItemChanged(position);
    }

    public void notifyItemInserted(int position) {
        mAdapter.notifyItemInserted(position);
        mRecyclerView.scrollToPosition(position);
    }
}
+4
source share
2 answers

recyclerView onPostExecute , onPostExecute context, recyclerView.

FetchExercise ExerciseDataProvider, activity context ExerciseDataProvider, async FetchExercise, : AsyncTask

public class MyCustomTask extends AsyncTask<Void, Void, Long> {
    private Context mContext;
        public MyCustomTask (Context context){
           mContext = context;
        }
        protected void onPostExecute(Long result) {
           //use mContext to update recycler view
        }
    }
}

context recyclerView.


UPDATE

1

interface, activity , data provider class activity context data provider class.

public class ExampleDataProviderFragment extends Fragment {
    private AbstractDataProvider mDataProvider;

    //Define an interface that will notify your activity of data set change
    public interface EventListener {
        void onNotifyDataSetChanged();
    }

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

        setRetainInstance(true); 

        //Pass activity context to ExerciseDataProvider
        mDataProvider = new ExerciseDataProvider(getActivity());
    }

    public AbstractDataProvider getDataProvider() {
        return mDataProvider;
    }
}

2

context ExerciseDataProvider , .

public class ExerciseDataProvider extends AbstractDataProvider {
    private List<ConcreteData> mData;
    private ConcreteData mLastRemovedData;
    private int mLastRemovedPosition = -1;

    //Add context parameter to constructor
    public ExerciseDataProvider(Context context) {

        //Pass context to async task

        new FetchExercise(context).execute();
        mData = new LinkedList<>();
    }

    class FetchExercise extends AsyncTask<Void,Void,Integer> {
        Context mContext;

        public FetchExercise(Context context) {
            mContext = context;
        }

        @Override
        protected Integer doInBackground(Void... params) {
            ...
            return 1;
        }

        @Override
        protected void onPostExecute(Integer result) {
            super.onPostExecute(result);

            //Typecast context to interface defined above 
            //and notify dataset changes by calling its method

            ExampleDataProviderFragment.EventListener eventListener = (ExampleDataProviderFragment.EventListener)mContext;
            eventListener.onNotifyDataSetChanged();

        }
    }
}

3

interface activity class recyclerView adapter

public class DraggableSwipeableExampleActivity extends AppCompatActivity 
    implements ExampleDataProviderFragment.EventListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
    }

    //implement interface method and notify recyclerview of changes
    @Override
    public void onNotifyDataSetChanged() {
        Fragment fragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_LIST_VIEW);

        // you might need to change visibility of `mWrappedAdapter` in the fragment that defines it or create a getter for it so that you can access it here
        ((RecyclerListViewFragment) fragment).mWrappedAdapter.notifyDataSetChanged(); 

    }
 ...
}
+3

, @random , Recycle view post.

@Override
protected void onPostExecute(Void aVoid) {
    mRecyclerViewAdapter.notifyDataSetChanged();
    super.onPostExecute(aVoid);
}

- , / - , :

@Override
protected void onPostExecute(Void aVoid) {
    mRecyclerViewAdapter.notifyItemRemoved(itemposition); // or item added
    mRecyclerViewAdapter.notifyDataSetChanged();
    super.onPostExecute(aVoid);
}

, !

0

All Articles