2015-11-02 40 views
1

基本上,我試圖以編程方式找出有多少物品將適合RecyclerView(當然,對用戶可見),以確定其中有多少物品從緩存中獲取。查找有多少個RecyclerView物品在創建之前適合屏幕

我正在使用LinearLayoutManager。

此外,我意識到LinearLayoutManager方法findLastVisibleItemPosition,但顯然它在這種情況下是無用的,因爲我們正在談論之前的初始化時間,而不是之後(所以它返回-1)。

嘗試閱讀文檔或思考創造性但高效的想法,但我一無所知。

任何想法?

回答

0

這聽起來其實很有趣,但只有當你的高度(垂直滾動)或寬度(水平滾動)是固定的,這意味着沒有wrap_content。

沒有示例代碼並沒有什麼在這裏測試:

  1. getCount創建一個setter一個適配器,獲取的情況下返回您的數據源是空/空
  2. getCount回報至少1如果你的數據是空/空
  3. 確保onBindViewHolder()可以處理空/不存在的數據
  4. 添加OnChildAttachStateChangeListener您RecyclerView,每次聽衆得到稱爲,使用viewview.post(new Runnable() {...increase adapters getCount...adapter.notifyItemInserted()}(可運行是必要的,以避免崩潰+燒傷)
  5. OnChildAttachStateChangeListener再次被調用>>>比較getCountfindLastVisibleItemPosition。如果getCount > findLastVisibleItemPosition + 1刪除該監聽器。固定大小的意見嵌入ListView的數量是findLastVisibleItemPosition + 1
  6. 讓您的數據,並將其設置爲您轉接,呼叫notifyDataSetChanged
  7. 確保getCount從現在開始返回數據源的長度。

你可以隱藏loadingscreen後面的列表視圖,也可以設置孩子的意見,以無形之中onBindViewHolder

編輯:

  1. 創建它返回一個荒謬的適配器沒有數據設置時的高計數,並確保它正確處理丟失的數據onBindViewHolder
  2. 延長LinearLayoutManager和超級調用後覆蓋onLayoutChildren()如果getItemCount() > getChildCount() getChildCount()是將在您的RecyclerView

MainActivity.class

public class MainActivity extends AppCompatActivity { 

     private PreCountingAdapter mAdapter; 
     private RecyclerView mRecyclerView; 
     private PreCountLinearLayoutManager mPreCountLayoutManager; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 
      mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
      mPreCountLayoutManager = new PreCountLinearLayoutManager(this, 
        LinearLayoutManager.VERTICAL, false); 
      mPreCountLayoutManager.setListener(new PreCountLinearLayoutManager.OnPreCountedListener() { 
       @Override 
       public void onPreCounted(int count) { 
        mPreCountLayoutManager.setListener(null); 
        loadData(count); 
       } 
      }); 
      mRecyclerView.setLayoutManager(mPreCountLayoutManager); 
      mAdapter = new PreCountingAdapter(); 
      mRecyclerView.setAdapter(mAdapter); 
     } 

     private void loadData(final int visibleItemCount) { 
      // load data here, probably asynchronously, 
      // for simplicity just an String Array with size visibleItemCount 
      final List<String> data = new ArrayList<>(); 
      for (int i = 0; i < visibleItemCount; i++) { 
       data.add(String.format("child number #%d", i)); 
      } 
      mRecyclerView.post(new Runnable() { 
       @Override 
       public void run() { 
        mAdapter.swapData(data); 
       } 
      }); 
     } 

     @Override 
     protected void onDestroy() { 
      mPreCountLayoutManager.setListener(null); 
      super.onDestroy(); 
     } 
    } 

PreCountLinearLayoutManager可見瀏覽的數量。類

public class PreCountLinearLayoutManager extends LinearLayoutManager { 
     private OnPreCountedListener mListener; 

     public interface OnPreCountedListener { 
      void onPreCounted(int count); 
     } 

     public PreCountLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { 
      super(context, orientation, reverseLayout); 
     } 

     @Override 
     public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 
      super.onLayoutChildren(recycler, state); 
      if (getItemCount() > getChildCount()) { 
       if (mListener != null) { 
        mListener.onPreCounted(getChildCount()); 
       } 
      } 
     } 

     public void setListener(OnPreCountedListener listener) { 
      mListener = listener; 
     } 
    } 

PreCountingAdapter.class

public class PreCountingAdapter extends RecyclerView.Adapter<PreCountingAdapter.ViewHolder> { 

     private List<String> mData; 

     public void swapData(List<String> data) { 
      mData = data; 
      notifyDataSetChanged(); 
     } 

     public class ViewHolder extends RecyclerView.ViewHolder { 

      View mItemView; 
      TextView mTextView; 

      public ViewHolder(View itemView) { 
       super(itemView); 
       mTextView = (TextView) itemView.findViewById(R.id.text_view); 
       mItemView = itemView; 
      } 
     } 

     @Override 
     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 
      return new ViewHolder(inflater.inflate(R.layout.recycler_child, parent, false)); 
     } 

     @Override 
     public void onBindViewHolder(ViewHolder holder, int position) { 
      if (mData == null) { 
       // we are in precounting stage 
       holder.mItemView.setVisibility(View.INVISIBLE); 
      } else { 
       String item = mData.get(position); 
       holder.mItemView.setVisibility(View.VISIBLE); 
       holder.mTextView.setText(item); 
      } 
     } 

     @Override 
     public int getItemCount() { 
      return mData == null ? Integer.MAX_VALUE : mData.size(); 
     } 

    } 
+0

我測試了,自從上次查看永遠不會被連接將無法工作。 (Doh,在寫作時對我應該是顯而易見的) –

+0

增加了另一個解決方案,簡單地進行了測試,並且工作到目前爲止。 –

+0

你的意思是什麼?它從來都不是固定的,它總是跨越幾乎所有可用空間(match_parent),就像Android中的大多數視圖一樣。 另外,你能否更好地解釋爲什麼你的解決方案應該工作? P.S.我認爲更簡單的方法是實時計算回收站視圖的高度,並根據每個項目的高度來劃分(然後需要以編程方式或從維度xml進行設置,因此在創建項目本身...) – Jjang