1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 package com.example.android.supportv7.widget;
19 
20 import android.app.Activity;
21 import android.content.Context;
22 import android.os.Bundle;
23 import android.view.Menu;
24 import android.view.MenuItem;
25 import android.view.ViewGroup;
26 import android.widget.TextView;
27 
28 import androidx.recyclerview.widget.AsyncListUtil;
29 import androidx.recyclerview.widget.LinearLayoutManager;
30 import androidx.recyclerview.widget.RecyclerView;
31 
32 import com.example.android.supportv7.Cheeses;
33 
34 /**
35  * A sample Activity to demonstrate capabilities of {@link AsyncListUtil}.
36  */
37 public class AsyncListUtilActivity extends Activity {
38 
39     private static final String TAG = "AsyncListUtilActivity";
40 
41     private RecyclerView mRecyclerView;
42 
43     private LinearLayoutManager mLinearLayoutManager;
44 
45     @Override
onCreate(Bundle savedInstanceState)46     protected void onCreate(Bundle savedInstanceState) {
47         super.onCreate(savedInstanceState);
48 
49         mRecyclerView = new RecyclerView(this);
50         mLinearLayoutManager = new LinearLayoutManager(this);
51         mRecyclerView.setLayoutManager(mLinearLayoutManager);
52         mRecyclerView.setHasFixedSize(true);
53         final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
54                 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
55         mRecyclerView.setLayoutParams(layoutParams);
56         mRecyclerView.setAdapter(new AsyncAdapter());
57         setContentView(mRecyclerView);
58     }
59 
60     @Override
onCreateOptionsMenu(Menu menu)61     public boolean onCreateOptionsMenu(Menu menu) {
62         super.onCreateOptionsMenu(menu);
63         menu.add("Layout").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
64         return true;
65     }
66 
67     @Override
onOptionsItemSelected(MenuItem item)68     public boolean onOptionsItemSelected(MenuItem item) {
69         mRecyclerView.requestLayout();
70         return super.onOptionsItemSelected(item);
71     }
72 
73     private static class TextViewHolder extends RecyclerView.ViewHolder {
74         TextView textView;
TextViewHolder(Context context)75         public TextViewHolder(Context context) {
76             super(new TextView(context));
77             textView = (TextView) itemView;
78         }
79     }
80 
81     private class AsyncAdapter extends RecyclerView.Adapter<TextViewHolder> {
82 
83         private AsyncListUtil<String> mAsyncListUtil;
84 
AsyncAdapter()85         AsyncAdapter() {
86             mAsyncListUtil = new AsyncStringListUtil();
87         }
88 
89         @Override
onCreateViewHolder(ViewGroup parent, int viewType)90         public TextViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
91             return new TextViewHolder(parent.getContext());
92         }
93 
94         @Override
onBindViewHolder(TextViewHolder holder, int position)95         public void onBindViewHolder(TextViewHolder holder, int position) {
96             final String itemString = mAsyncListUtil.getItem(position);
97             if (itemString == null) {
98                 holder.textView.setText("loading...");
99             } else {
100                 holder.textView.setText(itemString);
101             }
102         }
103 
104         @Override
getItemCount()105         public int getItemCount() {
106             return mAsyncListUtil.getItemCount();
107         }
108     }
109 
110     private class AsyncStringListUtil extends AsyncListUtil<String> {
111 
112         private static final int TILE_SIZE = 5;
113 
114         private static final long DELAY_MS = 500;
115 
AsyncStringListUtil()116         public AsyncStringListUtil() {
117             super(String.class, TILE_SIZE,
118                     new AsyncListUtil.DataCallback<String>() {
119                         @Override
120                         public int refreshData() {
121                             return Cheeses.sCheeseStrings.length;
122                         }
123 
124                         @Override
125                         public void fillData(String[] data, int startPosition, int itemCount) {
126                             sleep();
127                             for (int i = 0; i < itemCount; i++) {
128                                 data[i] = Cheeses.sCheeseStrings[startPosition + i];
129                             }
130                         }
131 
132                         private void sleep() {
133                             try {
134                                 Thread.sleep(DELAY_MS);
135                             } catch (InterruptedException e) {
136                                 e.printStackTrace();
137                             }
138                         }
139                     },
140                     new AsyncListUtil.ViewCallback() {
141                         @Override
142                         public void getItemRangeInto(int[] outRange) {
143                             outRange[0] = mLinearLayoutManager.findFirstVisibleItemPosition();
144                             outRange[1] = mLinearLayoutManager.findLastVisibleItemPosition();
145                         }
146 
147                         @Override
148                         public void onDataRefresh() {
149                             mRecyclerView.getAdapter().notifyDataSetChanged();
150                         }
151 
152                         @Override
153                         public void onItemLoaded(int position) {
154                             mRecyclerView.getAdapter().notifyItemChanged(position);
155                         }
156                     });
157 
158             mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
159                 @Override
160                 public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
161                     onRangeChanged();
162                 }
163             });
164         }
165     }
166 }
167