├── 6632160680259649418.jpg ├── README.md └── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── sunofbeaches │ └── recyclerviewtest │ └── ApplicationTest.java ├── main ├── AndroidManifest.xml ├── java │ └── com │ │ └── sunofbeaches │ │ └── recyclerviewtest │ │ ├── MainActivity.java │ │ ├── MoreTypeActivity.java │ │ ├── adapters │ │ ├── GridViewAdapter.java │ │ ├── ListViewAdapter.java │ │ ├── MoreTypeAdapter.java │ │ ├── RecyclerViewBaseAdapter.java │ │ └── StaggerAdapter.java │ │ └── beans │ │ ├── Datas.java │ │ ├── ItemBean.java │ │ └── MoreTypeBean.java └── res │ ├── layout │ ├── activity_main.xml │ ├── activity_more_type_activity.xml │ ├── item_grid_view.xml │ ├── item_list_loader_more.xml │ ├── item_list_view.xml │ ├── item_stagger.xml │ ├── item_type_full_image.xml │ ├── item_type_left_title_right_image.xml │ └── item_type_three_image.xml │ ├── menu │ └── menu.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── pic_01.jpg │ ├── pic_02.jpg │ ├── pic_03.jpg │ ├── pic_04.jpg │ ├── pic_05.jpg │ ├── pic_06.jpg │ ├── pic_07.jpg │ ├── pic_08.jpg │ ├── pic_09.jpg │ ├── pic_10.jpg │ ├── pic_11.jpg │ └── pic_12.jpg │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── test └── java └── com └── sunofbeaches └── recyclerviewtest └── ExampleUnitTest.java /6632160680259649418.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/6632160680259649418.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RecyclerViewTest 2 | 这个项目是网易云课堂课程《Android控件之RecyclerView》的源码 3 | 4 | ![](https://github.com/TrillGates/RecyclerViewTest/blob/master/6632160680259649418.jpg) 5 | 6 | ###课程地址在网易云课堂里头 7 | 8 | 收费课程: 9 | 10 | http://study.163.com/provider/2401592/index.htm 11 | 12 | 免费课程: 13 | 14 | https://space.bilibili.com/44272436?spm_id_from=333.338.viewbox_report.7#/video 15 | 16 | 代码下载下来然后修改一下gradle的版本就跑起来可以了。 17 | 18 | 具体详情可以去看视频,欢迎start,长这么大很少在github上分享代码,往后会多点的啦! 19 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.sunofbeaches.recyclerviewtest" 9 | minSdkVersion 15 10 | targetSdkVersion 25 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:25.3.1' 26 | compile 'com.android.support:recyclerview-v7:25.3.1' 27 | compile 'com.android.support:cardview-v7:25.3.1' 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/trillgates/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/sunofbeaches/recyclerviewtest/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.os.Handler; 6 | import android.support.v4.widget.SwipeRefreshLayout; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.support.v7.widget.GridLayoutManager; 9 | import android.support.v7.widget.LinearLayoutManager; 10 | import android.support.v7.widget.RecyclerView; 11 | import android.support.v7.widget.StaggeredGridLayoutManager; 12 | import android.util.Log; 13 | import android.view.Menu; 14 | import android.view.MenuItem; 15 | import android.widget.Toast; 16 | 17 | import com.sunofbeaches.recyclerviewtest.adapters.GridViewAdapter; 18 | import com.sunofbeaches.recyclerviewtest.adapters.ListViewAdapter; 19 | import com.sunofbeaches.recyclerviewtest.adapters.RecyclerViewBaseAdapter; 20 | import com.sunofbeaches.recyclerviewtest.adapters.StaggerAdapter; 21 | import com.sunofbeaches.recyclerviewtest.beans.Datas; 22 | import com.sunofbeaches.recyclerviewtest.beans.ItemBean; 23 | 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | import java.util.Random; 27 | 28 | /** 29 | * 总结: 30 | * 1、首先我们要有控件,这个RecyclerView它呢是在V7包下的,所以我们要打开这个 Module settings里的依赖, 31 | * 添加RecyclerView的依赖,这样子才能在布局文件里使用RecyclerView这个控件。 32 | * 2、通过findViewById找到控件 33 | * 3、准备好数据 34 | * 4、设置布局管理器 35 | * 5、就是创建适配器 36 | * 6、设置适配器 37 | * 7、数据就可以现实出来了 38 | */ 39 | public class MainActivity extends AppCompatActivity { 40 | 41 | private static final String TAG = "MainActivity"; 42 | private RecyclerView mList; 43 | private List mData; 44 | private RecyclerViewBaseAdapter mAdapter; 45 | private SwipeRefreshLayout mRefreshLayout; 46 | 47 | @Override 48 | protected void onCreate(Bundle savedInstanceState) { 49 | super.onCreate(savedInstanceState); 50 | setContentView(R.layout.activity_main); 51 | //找到控件 52 | mList = (RecyclerView) this.findViewById(R.id.recycler_view); 53 | mRefreshLayout = (SwipeRefreshLayout) this.findViewById(R.id.refresh_layout); 54 | //准备数据 55 | /** 56 | * 准备数据,一般来说,我们在现实开发中,我们的数据是从网络中获取的,这里面只是演示。 57 | * 所以我们只是模拟数据,在现实开发中也是要模拟数据的,比如说,后台没有准备好的时候。 58 | */ 59 | initData(); 60 | //设置默认的显示样式为ListView的效果 61 | showList(true, false); 62 | 63 | //处理下啦刷新 64 | handlerDownPullUpdate(); 65 | } 66 | 67 | private void handlerDownPullUpdate() { 68 | 69 | mRefreshLayout.setColorSchemeResources(R.color.colorPrimary, R.color.colorPrimaryDark, R.color.colorAccent); 70 | mRefreshLayout.setEnabled(true); 71 | mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 72 | @Override 73 | public void onRefresh() { 74 | //在这里面去执行刷新数据的操作 75 | /** 76 | * 当我们在顶部,下拉的时候 ,这个方法就会被出发 77 | * 但是,这个方法是MainThread是主线程,不可以执行耗时操作。 78 | * 一般来说,我们去请求数据在开一个线程去获取 79 | * //这里面演示的话,我直接添加一条数据 80 | */ 81 | //添加数据 82 | ItemBean data = new ItemBean(); 83 | data.title = "我是新添加的数据..."; 84 | data.icon = R.mipmap.pic_09; 85 | mData.add(0, data); 86 | //更新UI 87 | new Handler().postDelayed(new Runnable() { 88 | @Override 89 | public void run() { 90 | //这里要做两件事,一件是让刷新停止,另外一件则是要更新列表 91 | mAdapter.notifyDataSetChanged(); 92 | mRefreshLayout.setRefreshing(false); 93 | } 94 | }, 3000); 95 | } 96 | }); 97 | 98 | } 99 | 100 | private void initListener() { 101 | 102 | mAdapter.setOnItemClickListener(new RecyclerViewBaseAdapter.OnItemClickListener() { 103 | @Override 104 | public void onItemClick(int position) { 105 | //这里处理条目的点击事件,该干嘛就干嘛,跳转的就跳转... 106 | Toast.makeText(MainActivity.this, "您点击的是第" + position + "个条目", Toast.LENGTH_SHORT).show(); 107 | } 108 | }); 109 | 110 | //这里面去处理上拉加载更多 111 | if (mAdapter instanceof ListViewAdapter) { 112 | ((ListViewAdapter) mAdapter).setOnRefreshListener(new ListViewAdapter.OnRefreshListener() { 113 | @Override 114 | public void onUpPullRefresh(final ListViewAdapter.LoaderMoreHolder loaderMoreHolder) { 115 | //这里面去加载更多的数据,同样,需要在子线程中完成,这里仅作演示 116 | 117 | //更新UI 118 | new Handler().postDelayed(new Runnable() { 119 | @Override 120 | public void run() { 121 | 122 | Random random = new Random(); 123 | 124 | if (random.nextInt() % 2 == 0) { 125 | ItemBean data = new ItemBean(); 126 | data.title = "我是新添加的数据..."; 127 | data.icon = R.mipmap.pic_09; 128 | mData.add(data); 129 | 130 | //这里要做两件事,一件是让刷新停止,另外一件则是要更新列表 131 | mAdapter.notifyDataSetChanged(); 132 | loaderMoreHolder.update(loaderMoreHolder.LOADER_STATE_NORMAL); 133 | } else { 134 | loaderMoreHolder.update(loaderMoreHolder.LOADER_STATE_RELOAD); 135 | } 136 | 137 | } 138 | }, 3000); 139 | } 140 | }); 141 | } 142 | } 143 | 144 | /** 145 | * 这个方法用于模拟数据 146 | */ 147 | private void initData() { 148 | //List---->Adapter------>setAdapter------>显示数据。 149 | //创建数据集合 150 | mData = new ArrayList<>(); 151 | 152 | //创建模拟数据 153 | for (int i = 0; i < Datas.icons.length; i++) { 154 | //创建数据对象 155 | ItemBean data = new ItemBean(); 156 | data.icon = Datas.icons[i]; 157 | data.title = "我是第 " + i + " 个条目"; 158 | //添加到集合里头 159 | mData.add(data); 160 | } 161 | } 162 | 163 | 164 | @Override 165 | public boolean onCreateOptionsMenu(Menu menu) { 166 | getMenuInflater().inflate(R.menu.menu, menu); 167 | return super.onCreateOptionsMenu(menu); 168 | } 169 | 170 | @Override 171 | public boolean onOptionsItemSelected(MenuItem item) { 172 | 173 | int itemId = item.getItemId(); 174 | 175 | switch (itemId) { 176 | 177 | //ListView的部分 178 | case R.id.list_view_vertical_stander: 179 | Log.d(TAG, "点击了ListView里头的垂直标准"); 180 | showList(true, false); 181 | break; 182 | case R.id.list_view_vertical_reverse: 183 | Log.d(TAG, "点击了ListView里头的垂直反向"); 184 | showList(true, true); 185 | break; 186 | case R.id.list_view_horizontal_stander: 187 | Log.d(TAG, "点击了ListView里头的水平标准"); 188 | showList(false, false); 189 | break; 190 | case R.id.list_view_horizontal_reverse: 191 | Log.d(TAG, "点击了ListView里头的水平反向"); 192 | showList(false, true); 193 | break; 194 | 195 | //GridView部分 196 | case R.id.grid_view_vertical_stander: 197 | showGrid(true, false); 198 | break; 199 | case R.id.grid_view_vertical_reverse: 200 | showGrid(true, true); 201 | break; 202 | case R.id.grid_view_horizontal_stander: 203 | showGrid(false, false); 204 | break; 205 | case R.id.grid_view_horizontal_reverse: 206 | showGrid(false, true); 207 | break; 208 | 209 | //瀑布流部分 210 | case R.id.stagger_view_vertical_stander: 211 | showStagger(true, false); 212 | break; 213 | case R.id.stagger_view_vertical_reverse: 214 | showStagger(true, true); 215 | break; 216 | case R.id.stagger_view_horizontal_stander: 217 | showStagger(false, false); 218 | break; 219 | case R.id.stagger_view_horizontal_reverse: 220 | showStagger(false, true); 221 | break; 222 | 223 | // 多种条目类型被点击了 224 | case R.id.more_type: 225 | 226 | //跳到一个新的Activity里面去实现这个功能 227 | Intent intent = new Intent(this, MoreTypeActivity.class); 228 | startActivity(intent); 229 | break; 230 | 231 | } 232 | 233 | return super.onOptionsItemSelected(item); 234 | } 235 | 236 | /** 237 | * 这个方法用于实现瀑布流的效果 238 | */ 239 | private void showStagger(boolean isVertical, boolean isReverse) { 240 | //准备布局管理器 241 | StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, isVertical ? StaggeredGridLayoutManager.VERTICAL : StaggeredGridLayoutManager.HORIZONTAL); 242 | //设置布局管理器的方向 243 | layoutManager.setReverseLayout(isReverse); 244 | 245 | //设置布局管理器到RecyclerView里 246 | mList.setLayoutManager(layoutManager); 247 | 248 | //创建适配器 249 | mAdapter = new StaggerAdapter(mData); 250 | 251 | //设置适配器 252 | mList.setAdapter(mAdapter); 253 | 254 | //初始化事件 255 | initListener(); 256 | 257 | } 258 | 259 | /** 260 | * 这个方法用于实现和GridView一样的效果 261 | */ 262 | private void showGrid(boolean isVertical, boolean isReverse) { 263 | 264 | //创建布局管理器 265 | GridLayoutManager layoutManager = new GridLayoutManager(this, 3); 266 | //设置水平还是垂直 267 | layoutManager.setOrientation(isVertical ? GridLayoutManager.VERTICAL : GridLayoutManager.HORIZONTAL); 268 | //设置标准(正向)还是反向的 269 | layoutManager.setReverseLayout(isReverse); 270 | 271 | //设置布局管理器 272 | mList.setLayoutManager(layoutManager); 273 | 274 | //创建适配器 275 | mAdapter = new GridViewAdapter(mData); 276 | 277 | //设置适配器 278 | mList.setAdapter(mAdapter); 279 | 280 | //初始化事件 281 | initListener(); 282 | } 283 | 284 | /** 285 | * 这个方法用于现实ListView一样的效果 286 | */ 287 | private void showList(boolean isVertical, boolean isReverse) { 288 | //RecyclerView需要设置样式,其实就是设置布局管理器 289 | LinearLayoutManager layoutManager = new LinearLayoutManager(this); 290 | //设置布局管理器来控制 291 | //设置水平还是垂直 292 | layoutManager.setOrientation(isVertical ? LinearLayoutManager.VERTICAL : LinearLayoutManager.HORIZONTAL); 293 | //设置标准(正向)还是反向的 294 | layoutManager.setReverseLayout(isReverse); 295 | 296 | mList.setLayoutManager(layoutManager); 297 | //创建适配器 298 | mAdapter = new ListViewAdapter(mData); 299 | //设置到RecyclerView里头 300 | mList.setAdapter(mAdapter); 301 | 302 | //初始化事件 303 | initListener(); 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/MoreTypeActivity.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.util.Log; 9 | 10 | import com.sunofbeaches.recyclerviewtest.adapters.MoreTypeAdapter; 11 | import com.sunofbeaches.recyclerviewtest.beans.Datas; 12 | import com.sunofbeaches.recyclerviewtest.beans.MoreTypeBean; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.Random; 17 | 18 | /** 19 | * Created by TrillGates on 17/4/4. 20 | * God bless my code! 21 | */ 22 | public class MoreTypeActivity extends AppCompatActivity { 23 | 24 | private static final String TAG = "MoreTypeActivity"; 25 | private RecyclerView mRecyclerView; 26 | private List mData; 27 | 28 | @Override 29 | protected void onCreate(@Nullable Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_more_type_activity); 32 | 33 | //find the view here 34 | mRecyclerView = (RecyclerView) this.findViewById(R.id.more_type_list); 35 | 36 | //准备数据 37 | 38 | mData = new ArrayList<>(); 39 | 40 | initDatas(); 41 | 42 | //创建和设置布局管理器 43 | LinearLayoutManager layoutManager = new LinearLayoutManager(this); 44 | mRecyclerView.setLayoutManager(layoutManager); 45 | 46 | //创建适配器 47 | MoreTypeAdapter adapter = new MoreTypeAdapter(mData); 48 | 49 | //设置适配器 50 | mRecyclerView.setAdapter(adapter); 51 | 52 | 53 | } 54 | 55 | private void initDatas() { 56 | Random random = new Random(); 57 | 58 | for (int i = 0; i < Datas.icons.length; i++) { 59 | MoreTypeBean data = new MoreTypeBean(); 60 | data.pic = Datas.icons[i]; 61 | data.type = random.nextInt(3); 62 | Log.d(TAG, "type == " + data.type); 63 | mData.add(data); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/adapters/GridViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest.adapters; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | 6 | import com.sunofbeaches.recyclerviewtest.R; 7 | import com.sunofbeaches.recyclerviewtest.beans.ItemBean; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by TrillGates on 17/4/3. 13 | * God bless my code! 14 | */ 15 | public class GridViewAdapter extends RecyclerViewBaseAdapter { 16 | 17 | public GridViewAdapter(List data) { 18 | super(data); 19 | } 20 | 21 | @Override 22 | protected View getSubView(ViewGroup parent, int viewType) { 23 | //在这创建条目的UI 24 | View view = View.inflate(parent.getContext(), R.layout.item_grid_view, null); 25 | return view; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/adapters/ListViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest.adapters; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | import android.widget.LinearLayout; 7 | import android.widget.TextView; 8 | 9 | import com.sunofbeaches.recyclerviewtest.R; 10 | import com.sunofbeaches.recyclerviewtest.beans.ItemBean; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * Created by TrillGates on 17/4/3. 16 | * God bless my code! 17 | */ 18 | public class ListViewAdapter extends RecyclerViewBaseAdapter { 19 | 20 | //普通的条目类型 21 | public static final int TYPE_NORMAL = 0; 22 | //加载更多 23 | public static final int TYPE_LOADER_MORE = 1; 24 | private OnRefreshListener mUpPullRefreshListener; 25 | 26 | public ListViewAdapter(List data) { 27 | super(data); 28 | } 29 | 30 | 31 | @Override 32 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 33 | 34 | View view = getSubView(parent, viewType); 35 | if (viewType == TYPE_NORMAL) { 36 | return new InnerHolder(view); 37 | } else { 38 | return new LoaderMoreHolder(view); 39 | } 40 | } 41 | 42 | 43 | @Override 44 | protected View getSubView(ViewGroup parent, int viewType) { 45 | View view; 46 | //根据类型来创建view 47 | 48 | if (viewType == TYPE_NORMAL) { 49 | // 50 | view = View.inflate(parent.getContext(), R.layout.item_list_view, null); 51 | } else { 52 | //这个是加载更多的 53 | view = View.inflate(parent.getContext(), R.layout.item_list_loader_more, null); 54 | } 55 | 56 | 57 | return view; 58 | } 59 | 60 | /** 61 | * 这个方法是用于绑定holder的,一般用来设置数据 62 | * 63 | * @param holder 64 | * @param position 65 | */ 66 | @Override 67 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 68 | 69 | if (getItemViewType(position) == TYPE_NORMAL && holder instanceof InnerHolder) { 70 | //在这里设置数据 71 | ((InnerHolder) holder).setData(mData.get(position), position); 72 | } else if (getItemViewType(position) == TYPE_LOADER_MORE && holder instanceof LoaderMoreHolder) { 73 | ((LoaderMoreHolder) holder).update(LoaderMoreHolder.LOADER_STATE_LOADING); 74 | } 75 | 76 | 77 | } 78 | 79 | @Override 80 | public int getItemViewType(int position) { 81 | 82 | if (position == getItemCount() - 1) { 83 | //最后一个则返回加载更多、 84 | return TYPE_LOADER_MORE; 85 | } 86 | 87 | return TYPE_NORMAL; 88 | } 89 | 90 | /** 91 | * 设置刷的监听的接口 92 | */ 93 | public void setOnRefreshListener(OnRefreshListener listener) { 94 | this.mUpPullRefreshListener = listener; 95 | } 96 | 97 | //定义接口 98 | public interface OnRefreshListener { 99 | void onUpPullRefresh(LoaderMoreHolder loaderMoreHolder); 100 | } 101 | 102 | public class LoaderMoreHolder extends RecyclerView.ViewHolder { 103 | 104 | public static final int LOADER_STATE_LOADING = 0; 105 | public static final int LOADER_STATE_RELOAD = 1; 106 | public static final int LOADER_STATE_NORMAL = 2; 107 | 108 | private LinearLayout mLading; 109 | private TextView mReLoad; 110 | 111 | public LoaderMoreHolder(View itemView) { 112 | super(itemView); 113 | 114 | mLading = (LinearLayout) itemView.findViewById(R.id.loading); 115 | mReLoad = (TextView) itemView.findViewById(R.id.reload); 116 | 117 | mReLoad.setOnClickListener(new View.OnClickListener() { 118 | @Override 119 | public void onClick(View v) { 120 | //这里面要去触发加载数据 121 | update(LOADER_STATE_LOADING); 122 | } 123 | }); 124 | } 125 | 126 | 127 | public void update(int state) { 128 | 129 | //重置控件的状态 130 | mLading.setVisibility(View.GONE); 131 | mReLoad.setVisibility(View.GONE); 132 | 133 | switch (state) { 134 | case LOADER_STATE_LOADING: 135 | mLading.setVisibility(View.VISIBLE); 136 | //触发加载数据 137 | startLoaderMore(); 138 | break; 139 | 140 | case LOADER_STATE_RELOAD: 141 | mReLoad.setVisibility(View.VISIBLE); 142 | break; 143 | 144 | case LOADER_STATE_NORMAL: 145 | mLading.setVisibility(View.GONE); 146 | mReLoad.setVisibility(View.GONE); 147 | break; 148 | } 149 | } 150 | 151 | private void startLoaderMore() { 152 | if (mUpPullRefreshListener != null) { 153 | mUpPullRefreshListener.onUpPullRefresh(this); 154 | } 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/adapters/MoreTypeAdapter.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest.adapters; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import com.sunofbeaches.recyclerviewtest.R; 8 | import com.sunofbeaches.recyclerviewtest.beans.MoreTypeBean; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Created by TrillGates on 17/4/4. 14 | * God bless my code! 15 | */ 16 | public class MoreTypeAdapter extends RecyclerView.Adapter { 17 | 18 | 19 | //定义三个常量标识,因为我三种类型 20 | public static final int TYPE_FULL_IMAGE = 0; 21 | public static final int TYPE_RIGHT_IMAGE = 1; 22 | public static final int TYPE_THREE_IMAGES = 2; 23 | 24 | 25 | private final List mData; 26 | 27 | public MoreTypeAdapter(List data) { 28 | this.mData = data; 29 | } 30 | 31 | 32 | @Override 33 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 34 | 35 | 36 | /** 37 | * 根据ViewType来创建条目//这样子,条目就可以不一样了。 38 | */ 39 | View view; 40 | 41 | //TODO:这里面去创建ViewHolder 42 | if (viewType == TYPE_FULL_IMAGE) { 43 | view = View.inflate(parent.getContext(), R.layout.item_type_full_image, null); 44 | 45 | return new FullImageHolder(view); 46 | 47 | } else if (viewType == TYPE_RIGHT_IMAGE) { 48 | view = View.inflate(parent.getContext(), R.layout.item_type_left_title_right_image, null); 49 | 50 | return new RightImageHolder(view); 51 | } else { 52 | view = View.inflate(parent.getContext(), R.layout.item_type_three_image, null); 53 | return new ThreeImagesHolder(view); 54 | } 55 | 56 | } 57 | 58 | @Override 59 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 60 | //TODO:这里就不设置数据了 61 | } 62 | 63 | @Override 64 | public int getItemCount() { 65 | if (mData != null) { 66 | return mData.size(); 67 | } 68 | return 0; 69 | } 70 | 71 | //我们要复写一个方法,这个方法是根据条件来返条目类型的 72 | @Override 73 | public int getItemViewType(int position) { 74 | MoreTypeBean moreTypeBean = mData.get(position); 75 | if (moreTypeBean.type == 0) { 76 | return TYPE_FULL_IMAGE; 77 | } else if (moreTypeBean.type == 1) { 78 | return TYPE_RIGHT_IMAGE; 79 | } else { 80 | return TYPE_THREE_IMAGES; 81 | } 82 | } 83 | 84 | private class FullImageHolder extends RecyclerView.ViewHolder { 85 | 86 | public FullImageHolder(View itemView) { 87 | super(itemView); 88 | } 89 | } 90 | 91 | private class ThreeImagesHolder extends RecyclerView.ViewHolder { 92 | 93 | public ThreeImagesHolder(View itemView) { 94 | super(itemView); 95 | } 96 | } 97 | 98 | private class RightImageHolder extends RecyclerView.ViewHolder { 99 | 100 | public RightImageHolder(View itemView) { 101 | super(itemView); 102 | } 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/adapters/RecyclerViewBaseAdapter.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest.adapters; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | import android.widget.ImageView; 7 | import android.widget.TextView; 8 | 9 | import com.sunofbeaches.recyclerviewtest.R; 10 | import com.sunofbeaches.recyclerviewtest.beans.ItemBean; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * Created by TrillGates on 17/4/3. 16 | * God bless my code! 17 | */ 18 | public abstract class RecyclerViewBaseAdapter extends RecyclerView.Adapter { 19 | 20 | protected final List mData; 21 | private OnItemClickListener mOnItemClickListener; 22 | 23 | public RecyclerViewBaseAdapter(List data) { 24 | this.mData = data; 25 | } 26 | 27 | @Override 28 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 29 | View view = getSubView(parent, viewType); 30 | return new InnerHolder(view); 31 | } 32 | 33 | protected abstract View getSubView(ViewGroup parent, int viewType); 34 | 35 | /** 36 | * 这个方法是用于绑定holder的,一般用来设置数据 37 | * 38 | * @param holder 39 | * @param position 40 | */ 41 | @Override 42 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 43 | //在这里设置数据 44 | ((InnerHolder) holder).setData(mData.get(position), position); 45 | } 46 | 47 | 48 | /** 49 | * 反回条目的个数 50 | * 51 | * @return 52 | */ 53 | @Override 54 | public int getItemCount() { 55 | if (mData != null) { 56 | return mData.size(); 57 | } 58 | return 0; 59 | } 60 | 61 | public void setOnItemClickListener(OnItemClickListener listener) { 62 | //设置一个监听,其实,就是要设置一个接口,一个回调的接口 63 | this.mOnItemClickListener = listener; 64 | } 65 | 66 | 67 | /** 68 | * 编写回调的步骤 69 | * 1、创建这个接口 70 | * 2、定义借口内部的方法 71 | * 3、提供设置接口的方法(其实是外部实现) 72 | * 4、接口方法的调用 73 | */ 74 | 75 | 76 | public interface OnItemClickListener { 77 | void onItemClick(int position); 78 | } 79 | 80 | public class InnerHolder extends RecyclerView.ViewHolder { 81 | 82 | 83 | private ImageView mIcon; 84 | private TextView mTitle; 85 | private int mPosition; 86 | 87 | public InnerHolder(View itemView) { 88 | super(itemView); 89 | 90 | //找到条目的控件 91 | mIcon = (ImageView) itemView.findViewById(R.id.icon); 92 | mTitle = (TextView) itemView.findViewById(R.id.title); 93 | 94 | itemView.setOnClickListener(new View.OnClickListener() { 95 | @Override 96 | public void onClick(View v) { 97 | if (mOnItemClickListener != null) { 98 | mOnItemClickListener.onItemClick(mPosition); 99 | } 100 | } 101 | }); 102 | } 103 | 104 | /** 105 | * 这个方法用于设置数据 106 | */ 107 | public void setData(ItemBean itemBean, int position) { 108 | 109 | this.mPosition = position; 110 | //开始设置数据 111 | mIcon.setImageResource(itemBean.icon); 112 | mTitle.setText(itemBean.title); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/adapters/StaggerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest.adapters; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | 6 | import com.sunofbeaches.recyclerviewtest.R; 7 | import com.sunofbeaches.recyclerviewtest.beans.ItemBean; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by TrillGates on 17/4/3. 13 | * God bless my code! 14 | */ 15 | public class StaggerAdapter extends RecyclerViewBaseAdapter { 16 | 17 | public StaggerAdapter(List data) { 18 | super(data); 19 | } 20 | 21 | @Override 22 | protected View getSubView(ViewGroup parent, int viewType) { 23 | View view = View.inflate(parent.getContext(), R.layout.item_stagger, null); 24 | return view; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/beans/Datas.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest.beans; 2 | 3 | import com.sunofbeaches.recyclerviewtest.R; 4 | 5 | /** 6 | * Created by TrillGates on 17/3/11. 7 | * God bless my code! 8 | * For more : http://bbs.sunofbeaches.com 9 | */ 10 | public class Datas { 11 | public static int[] icons = { 12 | R.mipmap.pic_01, 13 | R.mipmap.pic_02, 14 | R.mipmap.pic_03, 15 | R.mipmap.pic_04, 16 | R.mipmap.pic_11, 17 | R.mipmap.pic_05, 18 | R.mipmap.pic_06, 19 | R.mipmap.pic_07, 20 | R.mipmap.pic_08, 21 | R.mipmap.pic_09, 22 | R.mipmap.pic_10, 23 | R.mipmap.pic_03, 24 | R.mipmap.pic_03, 25 | R.mipmap.pic_04, 26 | R.mipmap.pic_05, 27 | R.mipmap.pic_06, 28 | R.mipmap.pic_07, 29 | R.mipmap.pic_03, 30 | R.mipmap.pic_04, 31 | R.mipmap.pic_05, 32 | R.mipmap.pic_06, 33 | R.mipmap.pic_07, 34 | R.mipmap.pic_08, 35 | R.mipmap.pic_09, 36 | R.mipmap.pic_10, 37 | R.mipmap.pic_11, 38 | R.mipmap.pic_11, 39 | R.mipmap.pic_08, 40 | R.mipmap.pic_09, 41 | R.mipmap.pic_10, 42 | R.mipmap.pic_11, 43 | R.mipmap.pic_05, 44 | R.mipmap.pic_06, 45 | R.mipmap.pic_07, 46 | R.mipmap.pic_08, 47 | R.mipmap.pic_09, 48 | R.mipmap.pic_10, 49 | R.mipmap.pic_03, 50 | R.mipmap.pic_04, 51 | R.mipmap.pic_05, 52 | R.mipmap.pic_06, 53 | R.mipmap.pic_07, 54 | R.mipmap.pic_08, 55 | R.mipmap.pic_09, 56 | R.mipmap.pic_10, 57 | R.mipmap.pic_11, 58 | R.mipmap.pic_11, 59 | R.mipmap.pic_12}; 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/beans/ItemBean.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest.beans; 2 | 3 | /** 4 | * Created by TrillGates on 17/4/3. 5 | * God bless my code! 6 | */ 7 | public class ItemBean { 8 | public int icon; 9 | public String title; 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/sunofbeaches/recyclerviewtest/beans/MoreTypeBean.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest.beans; 2 | 3 | /** 4 | * Created by TrillGates on 17/4/4. 5 | * God bless my code! 6 | */ 7 | public class MoreTypeBean { 8 | public int type; 9 | public int pic; 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_more_type_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_grid_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 16 | 17 | 24 | 25 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_list_loader_more.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 18 | 19 | 20 | 21 | 27 | 28 | 32 | 33 | 38 | 39 | 40 | 41 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_list_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 14 | 15 | 16 | 19 | 20 | 21 | 28 | 29 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_stagger.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 17 | 18 | 26 | 27 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_type_full_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 15 | 18 | 19 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_type_left_title_right_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 16 | 20 | 21 | 27 | 28 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_type_three_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 19 | 20 | 21 | 27 | 28 | 32 | 33 | 40 | 41 | 48 | 49 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 10 | 13 | 16 | 19 | 20 | 21 | 22 | 25 | 26 | 29 | 32 | 35 | 38 | 39 | 40 | 43 | 44 | 47 | 50 | 53 | 56 | 57 | 58 | 61 | 62 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_01.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_02.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_03.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_04.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_05.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_06.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_07.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_08.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_09.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_10.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_11.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/pic_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-hdpi/pic_12.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrillGates/RecyclerViewTest/cd59d1c0258ee7d137c58a0fb326855ed5b3a095/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RecyclerViewTest 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/sunofbeaches/recyclerviewtest/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.sunofbeaches.recyclerviewtest; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } --------------------------------------------------------------------------------