2016-04-28 8 views
5

मुझे पता है कि इस सवाल को कई बार पहले पूछा गया था, लेकिन मैं उलझन में हूं कि कभी-कभी डेटा लोड हो जाता है और कभी-कभी डेटा सूची के अंत तक डेटा लोड नहीं होता है। साथ ही जब मैं सूची के माध्यम से तेजी से स्क्रॉलिंग करता हूं, और नया डेटा लोड हो गया है, लेकिन तुरंत यह मुझे सूची में पहले आइटम पर लौटाता है और सर्वर से अगले पृष्ठ से सभी नए लोड किए गए आइटम हटा देता है। तो यह दूसरी समस्या है और तीसरी समस्या यह है कि जब मैं SwipeRefreshLayout का उपयोग करके आइटम लोड करता हूं, तो मुझे सूची के अंत तक पहुंचने पर भी नए आइटम नहीं मिल रहे हैं।इन्फिनिटिव रीसाइक्लर व्यू मेरे लिए काम नहीं करता

मैं अपने प्रोजेक्ट में इस को लागू किया है: https://gist.github.com/ssinss/e06f12ef66c51252563e

list.setLayoutManager(manager); 
    list.setEmptyView(emptyView); 
    list.setItemAnimator(new DefaultItemAnimator()); 
    list.setAdapter(mAdapter); 

    loadJokes(1); 

    list.addOnScrollListener(new EndlessRecyclerOnScrollListener(manager) { 
     @Override 
     public void onLoadMore(final int current_page) { 
      loadMoreJokes(current_page); 
     } 
    }); 

यहाँ विधि मैं कहाँ सर्वर से अधिक आइटम लोड कर रहा हूँ है: यहाँ

private void loadMoreJokes(int current_page) { 
    StringRequest request = new StringRequest(Request.Method.GET, AppConfig.URL_GET_ALL_JOKES + current_page, 
      new Response.Listener<String>() { 
       @Override 
       public void onResponse(String response) { 
        hideDialog(); 
        try { 
         JSONObject object = new JSONObject(response); 
         boolean error = object.getBoolean("error"); 
         JSONArray jokes = object.getJSONArray("jokes"); 
         if (!error) { 
          for (int i = 0; i < jokes.length(); i++) { 
           JSONObject object1 = jokes.getJSONObject(i); 
           Joke joke = new Joke(); 
           joke.setId(object1.optInt("id")); 
           joke.setLikes(object1.optInt("likes")); 
           joke.setComments(object1.optInt("comments")); 
           joke.setJoke(object1.optString("joke")); 
           joke.setCreatedAt(object1.optString("created_at")); 
           joke.setName(object1.optString("user_name")); 
           joke.setImagePath(object1.optString("image_path")); 
           joke.setFacebookUserId(object1.optString("facebook_user_id")); 
           joke.setCategory(object1.optString("category")); 
           mJokes.add(joke); 
          } 
          menu.showMenu(true); 
         } 

         // Notify adapter that data has changed 
         mAdapter.notifyDataSetChanged(); 
        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
       } 
      }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      hideDialog(); 
      Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show(); 
     } 
    }); 

    AppController.getInstance().addToRequestQueue(request); 
} 

और विधि मैं कहाँ हूँ है जब कोई ऐप लॉन्च करता है तो पहले दृश्यमान आइटम लोड करना:

private void loadJokes(int page) { 
    pDialog.setMessage("Loading.."); 
    showDialog(); 

    StringRequest request = new StringRequest(Request.Method.GET, AppConfig.URL_GET_ALL_JOKES + page, 
      new Response.Listener<String>() { 
       @Override 
       public void onResponse(String response) { 
        mJokes.clear(); 
        hideDialog(); 
        try { 
         JSONObject object = new JSONObject(response); 
         boolean error = object.getBoolean("error"); 
         JSONArray jokes = object.getJSONArray("jokes"); 
         if (!error) { 
          for (int i = 0; i < jokes.length(); i++) { 
           JSONObject object1 = jokes.getJSONObject(i); 

           Joke joke = new Joke(); 
           joke.setId(object1.optInt("id")); 
           joke.setLikes(object1.optInt("likes")); 
           joke.setComments(object1.optInt("comments")); 
           joke.setJoke(object1.optString("joke")); 
           joke.setCreatedAt(object1.optString("created_at")); 
           joke.setName(object1.optString("user_name")); 
           joke.setImagePath(object1.optString("image_path")); 
           joke.setFacebookUserId(object1.optString("facebook_user_id")); 
           joke.setCategory(object1.optString("category")); 
           mJokes.add(joke); 
          } 
          menu.showMenu(true); 
         } 

         // Notify adapter that data has changed 
         mAdapter.notifyDataSetChanged(); 
        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
       } 
      }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      hideDialog(); 
      menu.showMenu(true); 
      Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show(); 
     } 
    }); 

    AppController.getInstance().addToRequestQueue(request); 
} 

और यह 0 हैविधि:

@Override 
public void onRefresh() { 
    new Handler().postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      refreshItems(); 
     } 
    }, 5000); 
} 

private void refreshItems() { 
    loadJokes(1); 

    mSwipeRefreshLayout.setRefreshing(false); 
} 

तो मैं अधिक कोड पोस्ट करने के लिए, मुझे पता है की जरूरत है। मुझे जितनी जल्दी हो सके इस समस्या को हल करने की ज़रूरत है। तो फिर, समस्याओं निम्नलिखित हैं:

  • तेजी से सूची स्क्रॉल करते हैं, नए आइटम लोड किया जा रहा है, लेकिन तुरंत बाद कि यह मुझे सूची की शुरुआत करने के लिए वापस आता है और जब मैं के अंत में जाना फिर से सूची, अधिक लोड जवाब नहीं देता है।

  • SwipRefreshLayout के साथ सूची को रीफ्रेश करने के बाद, स्क्रॉलिंग अंत में प्रतिक्रिया नहीं देती है।

नोट: स्क्रॉलिंग और लोडिंग नए आइटम केवल तभी काम कर रहे हैं जब मैं सूची के माध्यम से धीरे-धीरे जाता हूं और यदि मैं सूची को रीफ्रेश करने के लिए स्वाइप नहीं करता हूं।

संपादित करें:

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

    mContext = getActivity(); 
    mView = (CoordinatorLayout) view.findViewById(R.id.coordinatorLayout); 

    TextView tvEmptyText = (TextView) view.findViewById(R.id.tv_empty); 
    ImageView ivSignal = (ImageView) view.findViewById(R.id.iv_signal); 

    if (!ConnectionDetector.getInstance(getActivity()).isOnline() && mAdapter == null) { 
     tvEmptyText.setVisibility(View.VISIBLE); 
     ivSignal.setVisibility(View.VISIBLE); 
     showNoInternetSnackbar(); 
    } 

    // INITIALIZE RECYCLER VIEW 
    EmptyRecyclerView list = (EmptyRecyclerView) view.findViewById(R.id.list); 
    mJokes = new ArrayList<>(); 
    mAdapter = new RecyclerJokesAdapter(getActivity(), mJokes, JokesFragment.this, null); 

    // Progress dialog 
    pDialog = new ProgressDialog(getActivity()); 
    pDialog.setMessage("Please wait"); 
    pDialog.setIndeterminate(true); 
    pDialog.setCancelable(false); 

    showDialog(); 

    View emptyView = inflater.inflate(R.layout.layout_empty_view, container, false); 

    FloatingActionButton fab1 = (FloatingActionButton) view.findViewById(R.id.fab_funny); 
    FloatingActionButton fab2 = (FloatingActionButton) view.findViewById(R.id.fab_good_morning); 
    FloatingActionButton fab3 = (FloatingActionButton) view.findViewById(R.id.fab_good_night); 
    FloatingActionButton fab4 = (FloatingActionButton) view.findViewById(R.id.fab_all); 
    menu = (FloatingActionMenu) view.findViewById(R.id.menu_sort_jokes); 

    fab1.setOnClickListener(this); 
    fab2.setOnClickListener(this); 
    fab3.setOnClickListener(this); 
    fab4.setOnClickListener(this); 

    mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container); 
    mSwipeRefreshLayout.setOnRefreshListener(this); 
    mSwipeRefreshLayout.setColorSchemeResources(
      R.color.refresh_progress_1, 
      R.color.refresh_progress_2, 
      R.color.refresh_progress_3); 

    LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false); 

    list.setLayoutManager(manager); 
    list.setEmptyView(emptyView); 
    list.setItemAnimator(new DefaultItemAnimator()); 
    list.setAdapter(mAdapter); 

    if (ConnectionDetector.getInstance(mContext).isOnline()) { 
     loadJokes(1); 
    } else { 
     showNoInternetSnackbar(); 
     hideDialog(); 
    } 

    list.addOnScrollListener(new EndlessRecyclerOnScrollListener(manager) { 
     @Override 
     public void onLoadMore(final int current_page) { 
      loadMoreJokes(current_page); 
     } 
    }); 

    return view; 
} 
+0

अरे .. क्या आप कोड जोड़ सकते हैं जहां आपने 'mAdapter' फ़ील्ड शुरू किया था। – Jickson

+0

हां। एक मिनट में आओ –

+0

क्या आपने इस http://stackoverflow.com/a/30691092/855843 – Vilen

उत्तर

0

इस आवरण वर्ग

import android.content.Context; 
import android.support.annotation.NonNull; 
import android.support.v7.widget.RecyclerView; 

import java.util.List; 

public abstract class RecyclerWrapperAdapter<E> extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 

    protected Context context; 
    protected List<E> objects; 

    public void setContext(Context context) { 
     this.context = context; 
    } 

    public void setObjects(List<E> objects) { 
     this.objects = objects; 
     notifyDataSetChanged(); 
    } 

    public void add(@NonNull E object) { 
     objects.add(object); 
     notifyDataSetChanged(); 
    } 

    public void add(int position, @NonNull E object) { 
     if (position < objects.size() && position >= 0) { 
      objects.add(position, object); 
      notifyItemChanged(position); 
      notifyDataSetChanged(); 
     } else if (position >= objects.size()) { 
      objects.add(object); 
      notifyDataSetChanged(); 
     } 
    } 

    public void set(int position, @NonNull E object) { 
     if (position < objects.size() && position >= 0) { 
      objects.set(position, object); 
      notifyItemChanged(position); 
     } else if (position >= objects.size()) { 
      objects.add(object); 
      notifyDataSetChanged(); 
     } 
    } 

    public void remove(@NonNull E object) { 
     objects.remove(object); 
     notifyDataSetChanged(); 
    } 

    public void remove(int position) { 
     if (position >=0 && position < objects.size()) { 
      objects.remove(position); 
      notifyDataSetChanged(); 
     } 
    } 

    public void removeAll() { 
     objects.clear(); 
     notifyDataSetChanged(); 
    } 

    public E getItem(int position) { 
     return objects.get(position); 
    } 

    @Override 
    public int getItemCount() { 
     return objects.size(); 
    } 
} 
+0

ठीक है मैंने उन सभी चीजों को किया है। जब मैं आइटम लोड कर रहा हूं, तो मुझे पृष्ठ को लिखने और बढ़ने वाले पृष्ठ पर अब पृष्ठ को पास करने की आवश्यकता है .. –

+0

जब भी आप जोड़ रहे हों, तो उपरोक्त कोड में दिखाए गए 'add()' जैसे फ़ंक्शन का उपयोग करें। किया हुआ!! –

+0

मैं विधि में लोड कर रहा हूं 'loadJokes() ' –

1

onCreate विधि में उपयोग अब आप अपने एडाप्टर, recyclerView और सूची

List<MyObject> myList = new ArrayList<>(); 
recyclerViewAdapter = new RecyclerViewAdapter(context, myList) 
myRecyclerView.setAdapter(recyclerViewAdapter); 

प्रारंभ, जब भी आप डेटा लोड। अपने MyList करने के लिए डेटा जोड़ सकते हैं और अपने adpater पर notifyDataSetChange फोन

myList.add(data); 
recyclerViewAdapter.notifyDataSetChange(); 
+0

में जोड़ने का प्रयास करें मेरा संपादित प्रश्न देखें। –

+1

@DusanDimitrijevic जहां आपने अपना एडाप्टर प्रारंभ किया है? – Arshad

0

खैर मैं इस तरह से किया है:

MainActivity जावा

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener, onRecyclerViewListener { 

    private RecyclerView mRecyclerView; 
    private TextView tvEmptyView; 
    private LinearLayoutManager mLayoutManager; 
    private List<Object> studentList; 
    protected Handler handler; 
    private int count = 0; 
    private SwipeRefreshLayout swipeRefreshLayout; 
    private MyRecycleAdapter myRecycleAdapter; 

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


     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swiperefresh); 

     swipeRefreshLayout.setOnRefreshListener(this); 

     swipeRefreshLayout.setColorSchemeResources(R.color.blue, R.color.purple, R.color.green, R.color.orange); 

     tvEmptyView = (TextView) findViewById(R.id.empty_view); 
     mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView); 
     studentList = new ArrayList<Object>(); 
     handler = new Handler(); 
     loadData(); 

     mRecyclerView.setHasFixedSize(true); 

     mLayoutManager = new LinearLayoutManager(this); 
     mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 

     // use a linear layout manager 
     mRecyclerView.setLayoutManager(mLayoutManager); 

     myRecycleAdapter = new MyRecycleAdapter(mRecyclerView, studentList, R.layout.list_row, R.layout.progressbar_item, this); 
     myRecycleAdapter.setLoadMoreEnable(true); 
     myRecycleAdapter.setOnLoadMoreListener(new OnLoadMoreListener() { 
      @Override 
      public void onLoadMore() { 
       count++; 
       if (count == 4) { 
        count = 0; 
        myRecycleAdapter.setLoadMoreEnable(false); 
       } else { 
        myRecycleAdapter.setLoadMoreEnable(true); 
       } 

       //add null , so the adapter will check view_type and show progress bar at bottom 
       studentList.add(null); 
       myRecycleAdapter.notifyItemInserted(studentList.size() - 1); 

       handler.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         // remove progress item 
         studentList.remove(studentList.size() - 1); 
         myRecycleAdapter.notifyItemRemoved(studentList.size()); 
         //add items one by one 
         int start = studentList.size(); 
         int end = start + 20; 

         for (int i = start + 1; i <= end; i++) { 
          studentList.add(new Student("Student " + i, "AndroidStudent" + i + "@gmail.com")); 
          myRecycleAdapter.notifyItemInserted(studentList.size()); 
         } 
         myRecycleAdapter.setLoaded(); 
         //or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged(); 
        } 
       }, 1000); 
      } 
     }); 

     ItemViewHolderNew.setRecyclerListener(this); 

     mRecyclerView.setAdapter(myRecycleAdapter); 

     if (studentList.isEmpty()) { 
      mRecyclerView.setVisibility(View.GONE); 
      tvEmptyView.setVisibility(View.VISIBLE); 

     } else { 
      mRecyclerView.setVisibility(View.VISIBLE); 
      tvEmptyView.setVisibility(View.GONE); 
     } 
    } 

    private void loadData() { 
     for (int i = 1; i <= 20; i++) { 
      studentList.add(new Student("Student " + i, "androidstudent" + i + "@gmail.com")); 
     } 
    } 

    @Override 
    public void onRefresh() { 

     swipeRefreshLayout.setRefreshing(true); 

     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       swipeRefreshLayout.setRefreshing(false); 
      } 
     },5000); 
    } 

    @Override 
    public void onBindView(View view, final ItemViewHolderNew itemViewHolder) { 
     itemViewHolder.tvName = (TextView) view.findViewById(R.id.tvName); 
     itemViewHolder.tvEmailId = (TextView) view.findViewById(R.id.tvEmailId); 
    } 

    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, Object object, ItemViewHolderNew itemViewHolder) { 
     Student studentObj = (Student)object; 
     itemViewHolder.tvName.setText(studentObj.getName()); 
     itemViewHolder.tvEmailId.setText(studentObj.getEmailId()); 
     itemViewHolder.student= studentObj; 
    } 

    @Override 
    public void setClickListener(View view, ItemViewHolderNew itemViewHolder) { 
     Toast.makeText(view.getContext(), "OnClick :" + itemViewHolder.student.getName() + " \n " + itemViewHolder.student.getEmailId(), Toast.LENGTH_SHORT).show(); 
    } 

    public static class ItemViewHolderNew extends RecyclerView.ViewHolder{ 
     public TextView tvName, tvEmailId; 
     public Student student; 
     private static onRecyclerViewListener mListener; 

     public static void setRecyclerListener(onRecyclerViewListener listener){ 
      mListener = listener; 
     } 

     public ItemViewHolderNew(View itemView) { 
      super(itemView); 
      mListener.onBindView(itemView, this); 
      itemView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        setClick(v); 
       } 
      }); 
     } 
     private void setClick(View v) { 
      mListener.setClickListener(v, this); 
     } 
    } 
} 

OnLoadMoreListener जोड़ें।जावा इंटरफ़ेस

public interface OnLoadMoreListener { 
    void onLoadMore(); 
} 

मॉडल वर्ग के रूप में Student.java जोड़े

public class Student implements Serializable { 

    private static final long serialVersionUID = 1L; 
    private String name; 
    private String emailId; 
    public Student(String name, String emailId) { 
     this.name = name; 
     this.emailId = emailId; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getEmailId() { 
     return emailId; 
    } 

    public void setEmailId(String emailId) { 
     this.emailId = emailId; 
    } 

} 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" 
    tools:context=".MainActivity" 
    tools:showIn="@layout/activity_main"> 


    <android.support.v4.widget.SwipeRefreshLayout 
     android:id="@+id/swiperefresh" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <android.support.v7.widget.RecyclerView 
      android:id="@+id/recyclerView" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:scrollbars="vertical"> 

     </android.support.v7.widget.RecyclerView> 


    </android.support.v4.widget.SwipeRefreshLayout> 

    <TextView 
     android:id="@+id/empty_view" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:text="No Records Here !" 
     android:visibility="gone" /> 
</RelativeLayout> 

list_row.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:orientation="vertical" 
     android:layout_height="match_parent" 
     android:padding="5dp" 
     android:background="?android:selectableItemBackground"> 

     <TextView 
      android:id="@+id/tvName" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_margin="5dp" 
      android:text="Name" 
      android:textColor="@android:color/black" 
      android:textSize="18sp" /> 

     <TextView 
      android:id="@+id/tvEmailId" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/tvName" 
      android:layout_margin="5dp" 
      android:text="Email Id" 
      android:textColor="@android:color/black" 
      android:textSize="12sp" /> 

     <TextView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_margin="5dp" 
      android:text="Name" 
      android:textColor="@android:color/black" 
      android:textSize="18sp" /> 

     <TextView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/tvName" 
      android:layout_margin="5dp" 
      android:text="Email Id" 
      android:textColor="@android:color/black" 
      android:textSize="12sp" /> 
    </LinearLayout> 

</android.support.v7.widget.CardView> 

progressbar_item.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:gravity="center" 
    android:layout_width="match_parent" android:layout_height="match_parent"> 

    <ProgressBar 
     android:id="@+id/progressBar1" 
     android:layout_width="wrap_content" 
     android:layout_gravity="center_horizontal" 
     android:layout_height="wrap_content" /> 


</LinearLayout> 

अंतहीन, कड़ी चोट ताज़ा करने के लिए, लोड अधिक RecyclerView साथ ठीक काम कर रहा।

आशा है कि यह आपकी मदद करेगा।

0

वॉली RequestQueue नेटवर्क अनुरोधों के लिए थ्रेड पूल का उपयोग करता है।

/** Number of network request dispatcher threads to start. */ 
    private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4; 
जाहिर

, जब आप कर fast scrolling through the list अधिक अनुरोध जल्दी जल्दी में उत्पन्न कर रहे हैं।

एक संभावना है कि प्रतिक्रियाओं को अनुक्रमित/अनुक्रम से बाहर प्राप्त किया जाता है। साथ ही, यह संभव है कि "कोई और डेटा" प्रतिक्रियाएं/त्रुटि प्रतिक्रिया आदि डेटा के अगले पृष्ठ के साथ प्रतिक्रियाओं से पहले पहुंचें, जिससे आपके ऐप द्वारा अप्रत्याशित व्यवहार हो सकता है।

विशेष रूप से यह देखें कि यह आपके mJokes ArrayList सदस्य चर को कैसे प्रभावित करेगा।

संबंधित मुद्दे