1 /* 2 * Copyright (C) 2017 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 package com.example.android.support.content.demos; 18 19 import android.database.Cursor; 20 import android.net.Uri; 21 import android.os.Bundle; 22 import android.view.Menu; 23 import android.view.MenuItem; 24 import android.view.ViewGroup; 25 import android.widget.TextView; 26 27 import androidx.annotation.NonNull; 28 import androidx.appcompat.app.AppCompatActivity; 29 import androidx.appcompat.widget.Toolbar; 30 import androidx.contentpager.content.ContentPager; 31 import androidx.contentpager.content.ContentPager.ContentCallback; 32 import androidx.contentpager.content.LoaderQueryRunner; 33 import androidx.contentpager.content.Query; 34 import androidx.recyclerview.widget.LinearLayoutManager; 35 import androidx.recyclerview.widget.RecyclerView; 36 37 import com.google.android.material.floatingactionbutton.FloatingActionButton; 38 import com.google.android.material.snackbar.BaseTransientBottomBar; 39 import com.google.android.material.snackbar.Snackbar; 40 41 import java.util.Locale; 42 43 /** 44 * ContentPager demo activity. 45 */ 46 public class ContentPagerDemoActivity extends AppCompatActivity { 47 48 private static final int PAGE_SIZE = 20; 49 50 private RecyclerView mRecycler; 51 private ContentPager mPager; 52 private Adapter mAdapter; 53 private FloatingActionButton mFab; 54 private Menu mMenu; 55 private int mCurrentPage = -1; 56 57 @Override onCreate(Bundle savedInstanceState)58 protected void onCreate(Bundle savedInstanceState) { 59 super.onCreate(savedInstanceState); 60 setContentView(R.layout.activity_demo); 61 62 ContentPager.QueryRunner runner = new LoaderQueryRunner(this, getLoaderManager()); 63 mPager = new ContentPager(getContentResolver(), runner); 64 mAdapter = new Adapter(mPager, PAGE_SIZE); 65 66 mRecycler = (RecyclerView) findViewById(R.id.list); 67 mRecycler.setLayoutManager(new LinearLayoutManager(this)); 68 mRecycler.setAdapter(mAdapter); 69 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 70 setSupportActionBar(toolbar); 71 } 72 73 @Override onDestroy()74 protected void onDestroy() { 75 super.onDestroy(); 76 mPager.reset(); 77 } 78 79 @Override onCreateOptionsMenu(Menu menu)80 public boolean onCreateOptionsMenu(Menu menu) { 81 // Inflate the menu; this adds items to the action bar if it is present. 82 getMenuInflater().inflate(R.menu.menu_demo, menu); 83 mMenu = menu; 84 return true; 85 } 86 87 @Override onOptionsItemSelected(MenuItem item)88 public boolean onOptionsItemSelected(MenuItem item) { 89 90 switch (item.getItemId()) { 91 case R.id.action_load: 92 onLoadContent(); 93 break; 94 case R.id.action_previous: 95 onLoadPreviousPage(); 96 break; 97 case R.id.action_next: 98 onLoadNextPage(); 99 break; 100 } 101 // Handle action bar item clicks here. The action bar will 102 // automatically handle clicks on the Home/Up button, so long 103 // as you specify a parent activity in AndroidManifest.xml. 104 int id = item.getItemId(); 105 106 //noinspection SimplifiableIfStatement 107 if (id == R.id.action_load) { 108 return true; 109 } 110 111 return super.onOptionsItemSelected(item); 112 } 113 onLoadContent()114 private void onLoadContent() { 115 mAdapter.reset(UnpagedDemoDataProvider.URI); 116 mCurrentPage = 0; 117 mAdapter.loadPage(mCurrentPage); 118 119 updateOptionsMenu(); 120 } 121 onLoadNextPage()122 private void onLoadNextPage() { 123 mAdapter.loadPage(mCurrentPage + 1); 124 125 updateOptionsMenu(); 126 } 127 onLoadPreviousPage()128 private void onLoadPreviousPage() { 129 mAdapter.loadPage(mCurrentPage - 1); 130 131 updateOptionsMenu(); 132 } 133 updateOptionsMenu()134 private void updateOptionsMenu() { 135 MenuItem prev = mMenu.findItem(R.id.action_previous); 136 MenuItem next = mMenu.findItem(R.id.action_next); 137 138 int lastPage = (UnpagedDemoDataProvider.TOTAL_SIZE / PAGE_SIZE) - 1; 139 prev.setEnabled(mCurrentPage > 0); 140 next.setEnabled(mCurrentPage < lastPage); 141 } 142 143 private void msg(String msg) { 144 Snackbar.make( 145 mRecycler, 146 msg, BaseTransientBottomBar.LENGTH_LONG) 147 .setAction("Action", null).show(); 148 } 149 150 private final class Adapter extends RecyclerView.Adapter<Holder> implements ContentCallback { 151 152 private final ContentPager mPager; 153 private final int mPageSize; 154 155 private Uri mUri; 156 private Cursor mCursor; 157 158 private Adapter(ContentPager pager, int pageSize) { 159 mPager = pager; 160 mPageSize = pageSize; 161 } 162 163 private void reset(Uri uri) { 164 mUri = uri; 165 mCursor = null; 166 } 167 168 void loadPage(int page) { 169 if (page < 0 || page >= (UnpagedDemoDataProvider.TOTAL_SIZE / PAGE_SIZE)) { 170 throw new IndexOutOfBoundsException(); 171 } 172 173 mCurrentPage = page; 174 int offset = mCurrentPage * mPageSize; 175 mPager.query(mUri, null, ContentPager.createArgs(offset, mPageSize), null, this); 176 } 177 178 @Override 179 public Holder onCreateViewHolder(ViewGroup parent, int viewType) { 180 return new Holder(new TextView(ContentPagerDemoActivity.this)); 181 } 182 183 @Override 184 public void onBindViewHolder(Holder holder, int position) { 185 if (!mCursor.moveToPosition(position)) { 186 holder.view.setText("Nope, couldn't position cursor to: " + position); 187 return; 188 } 189 190 holder.view.setText(String.format(Locale.US, 191 "%d.%d (%d): %s", 192 mCurrentPage, 193 mCursor.getInt(0), 194 mCursor.getLong(2), 195 mCursor.getString(1))); 196 } 197 198 @Override 199 public int getItemCount() { 200 return mCursor == null ? 0 : mCursor.getCount(); 201 } 202 203 @Override 204 public void onCursorReady(@NonNull Query query, Cursor cursor) { 205 if (cursor == null) { 206 msg("Content query returned a null cursor: " + query.getUri()); 207 } 208 209 mCurrentPage = query.getOffset() / mPageSize; 210 mCursor = cursor; 211 notifyDataSetChanged(); 212 } 213 214 private int getCorpusSize(Bundle extras) { 215 return extras.getInt(ContentPager.EXTRA_TOTAL_COUNT, -1); 216 } 217 } 218 219 private class Holder extends RecyclerView.ViewHolder { 220 221 public final TextView view; 222 223 private Holder(TextView view) { 224 super(view); 225 this.view = view; 226 } 227 } 228 } 229