Adding AsyncListUtilActivity to Support7Demo

Bug: 20180767
Change-Id: Ib097e3aa0f4fa9179b6bfd743fa43b584e7860ce
diff --git a/samples/Support7Demos/AndroidManifest.xml b/samples/Support7Demos/AndroidManifest.xml
index b903f9a..e3337a6 100644
--- a/samples/Support7Demos/AndroidManifest.xml
+++ b/samples/Support7Demos/AndroidManifest.xml
@@ -375,6 +375,15 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".widget.AsyncListUtilActivity"
+                  android:label="@string/async_list_util"
+                  android:theme="@style/Theme.AppCompat">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv7.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".view.CardViewActivity"
                   android:label="@string/card_view"
                   android:theme="@style/Theme.AppCompat">
diff --git a/samples/Support7Demos/res/values/strings.xml b/samples/Support7Demos/res/values/strings.xml
index 5c87db9..98d2087 100644
--- a/samples/Support7Demos/res/values/strings.xml
+++ b/samples/Support7Demos/res/values/strings.xml
@@ -147,6 +147,7 @@
     <string name="linear_layout_manager">RecyclerView/Linear Layout Manager</string>
     <string name="grid_layout_manager">RecyclerView/Grid Layout Manager</string>
     <string name="staggered_grid_layout_manager">RecyclerView/Staggered Grid Layout Manager</string>
+    <string name="async_list_util">RecyclerView/AsyncListUtil</string>
     <string name="checkbox_orientation">Horz.</string>
     <string name="checkbox_reverse">Rev.</string>
     <string name="checkbox_layout_dir">Layout Dir</string>
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/AsyncListUtilActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/AsyncListUtilActivity.java
new file mode 100644
index 0000000..8ec3a23
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/AsyncListUtilActivity.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.example.android.supportv7.widget;
+
+import com.example.android.supportv7.Cheeses;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.util.AsyncListUtil;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * A sample Activity to demonstrate capabilities of {@link AsyncListUtil}.
+ */
+public class AsyncListUtilActivity extends Activity {
+
+    private static final String TAG = "AsyncListUtilActivity";
+
+    private RecyclerView mRecyclerView;
+
+    private LinearLayoutManager mLinearLayoutManager;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mRecyclerView = new RecyclerView(this);
+        mLinearLayoutManager = new LinearLayoutManager(this);
+        mRecyclerView.setLayoutManager(mLinearLayoutManager);
+        mRecyclerView.setHasFixedSize(true);
+        final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        mRecyclerView.setLayoutParams(layoutParams);
+        mRecyclerView.setAdapter(new AsyncAdapter());
+        setContentView(mRecyclerView);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        MenuItemCompat.setShowAsAction(menu.add("Layout"), MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        mRecyclerView.requestLayout();
+        return super.onOptionsItemSelected(item);
+    }
+
+    private static class TextViewHolder extends RecyclerView.ViewHolder {
+        TextView textView;
+        public TextViewHolder(Context context) {
+            super(new TextView(context));
+            textView = (TextView) itemView;
+        }
+    }
+
+    private class AsyncAdapter extends RecyclerView.Adapter<TextViewHolder> {
+
+        private AsyncListUtil<String> mAsyncListUtil;
+
+        AsyncAdapter() {
+            mAsyncListUtil = new AsyncStringListUtil();
+        }
+
+        @Override
+        public TextViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+            return new TextViewHolder(parent.getContext());
+        }
+
+        @Override
+        public void onBindViewHolder(TextViewHolder holder, int position) {
+            final String itemString = mAsyncListUtil.getItem(position);
+            if (itemString == null) {
+                holder.textView.setText("loading...");
+            } else {
+                holder.textView.setText(itemString);
+            }
+        }
+
+        @Override
+        public int getItemCount() {
+            return mAsyncListUtil.getItemCount();
+        }
+    }
+
+    private class AsyncStringListUtil extends AsyncListUtil<String> {
+
+        private static final int TILE_SIZE = 5;
+
+        private static final long DELAY_MS = 500;
+
+        public AsyncStringListUtil() {
+            super(String.class, TILE_SIZE,
+                    new AsyncListUtil.DataCallback<String>() {
+                        @Override
+                        public int refreshData() {
+                            return Cheeses.sCheeseStrings.length;
+                        }
+
+                        @Override
+                        public void fillData(String[] data, int startPosition, int itemCount) {
+                            sleep();
+                            for (int i = 0; i < itemCount; i++) {
+                                data[i] = Cheeses.sCheeseStrings[startPosition + i];
+                            }
+                        }
+
+                        private void sleep() {
+                            try {
+                                Thread.sleep(DELAY_MS);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    },
+                    new AsyncListUtil.ViewCallback() {
+                        @Override
+                        public void getItemRangeInto(int[] outRange) {
+                            outRange[0] = mLinearLayoutManager.findFirstVisibleItemPosition();
+                            outRange[1] = mLinearLayoutManager.findLastVisibleItemPosition();
+                        }
+
+                        @Override
+                        public void onDataRefresh() {
+                            mRecyclerView.getAdapter().notifyDataSetChanged();
+                        }
+
+                        @Override
+                        public void onItemLoaded(int position) {
+                            mRecyclerView.getAdapter().notifyItemChanged(position);
+                        }
+                    });
+
+            mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+                @Override
+                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+                    onRangeChanged();
+                }
+            });
+        }
+    }
+}