4

Je travaille sur un RecyclerView qui doit être Dragable & à glisser. Tout fonctionne parfaitement.Impossible de mettre à jour RecyclerView à partir de mon modèle Classe?

Les données sont récupérées dans une classe appelée ExerciseDataProvider & le code RV est un autre fragment RecyclerListViewFragment.

Le problème est que je ne peux pas notifier les données modifiées de FetchExercise sur la méthode postExecute. Donc, les données ne sont pas peuplées dans le RV.

S'il vous plaît me guider dans une bonne direction.

ACTIVITÉ

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(); 
    } 

Fournisseur de données

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); 
    } 
} 
+0

Vous ne mettez pas à jour l'interface utilisateur dans OnPostExecute –

+0

Définissez l'adaptateur dans OnPostExecute –

+0

@VeereshCharantimath Comment puis-je définir l'adaptateur dans OnPostExecute. Montre-moi du code. – user3467240

Répondre

3

Pour mettre à jour recyclerView de onPostExecute dans une classe de fournisseur de données, votre onPostExecute devrait avoir accès à context où votre recyclerView est défini.

Depuis votre FetchExercise tâche async est définie à l'intérieur ExerciseDataProvider classe, essayez passer activitycontext au constructeur de ExerciseDataProvider, puis le transmettre à FetchExercise tâche async comme décrit ici: getting context in 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 
     } 
    } 
} 

Utilisez le context mettre à jour le recyclerView.


MISE À JOUR

Étape 1

Définir un interface qui alertera votre activity de modifications de données mis dans une classe qui initialise votre data provider class et passer activity context au constructeur de 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; 
    } 
} 

Étape 2

Ajouter context paramètre constructeur de ExerciseDataProvider et l'utiliser pour notifier une activité qui implémente l'interface pour notifier le changement ensemble de données.

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(); 

     } 
    } 
} 

Étape 3

Mettre en oeuvre définis ci-dessus interface dans votre activity class et notify recyclerviewadapter à l'intérieur

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(); 

    } 
... 
} 
+0

en passant le contexte, je reçois beaucoup d'erreurs. Pouvez-vous juste le montrer dans mon code s'il vous plaît. – user3467240

+0

vérifier la réponse mise à jour – random

+0

Merci beaucoup. +1 et accepté – user3467240

0

Je pense que @random est correcte, vous devriez avisez votre point de vue Recycler le poste exécuter.

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

ou si vous avez fait quelque chose dans votre tâche async pour ajouter/supprimer quelque chose dans l'ensemble de données que vous feriez:

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

Hope it helps!