diff --git a/.gitignore b/.gitignore index 0bc28625a..31e68a426 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,14 @@ proguard/ .gradle .idea build +<<<<<<< HEAD +/build.gradle +/.idea/ + +build.gradle + +.idea/misc.xml +======= +.DS_Store + +/app/.gitignore diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 5ad3323c4..000000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -BaseRecyclerViewAdapterHelper \ No newline at end of file diff --git a/README-cn.md b/README-cn.md index 2b571f645..0161a4ec3 100644 --- a/README-cn.md +++ b/README-cn.md @@ -65,39 +65,106 @@ public class QuickAdapter extends BaseQuickAdapter { } } ``` -#如何添加item点击、长按事件 -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/chlid_click.gif) -```java -mQuickAdapter.setOnRecyclerViewItemClickListener(); -mQuickAdapter.setOnRecyclerViewItemLongClickListener(); -``` -#新增添加子布局多个控件的点击事件 Adapter ```java - protected void convert(BaseViewHolder helper, Status item) { - helper.setOnClickListener(R.id.tweetAvatar, new OnItemChildClickListener()) - .setOnClickListener(R.id.tweetName, new OnItemChildClickListener()); - } +mRecyclerView.addOnItemTouchListener(new OnItemClickListener( ){ + + @Override + public void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + + } + }); + +``` +#设置 item click 新增添加子布局多个控件的点击事件 +#设置 it item child click +首先需要添加需要点击触发的 childview id +``` + @Override + protected void convert(BaseViewHolder helper, Status item) { + helper.setText(R.id.tweetName, item.getUserName()) + .setText(R.id.tweetText, item.getText()) + .setText(R.id.tweetDate, item.getCreatedAt()) + .setVisible(R.id.tweetRT, item.isRetweet()) + .addOnClickListener(R.id.tweetAvatar) + .addOnClickListener(R.id.tweetName) + .addOnLongClickListener(R.id.tweetText) + .linkify(R.id.tweetText); + Glide.with(mContext).load(item.getUserAvatar()).crossFade().placeholder(R.mipmap.def_head).transform(new GlideCircleTransform(mContext)).into((ImageView) helper.getView(R.id.tweetAvatar)); + } ``` Activity ```java -mQuickAdapter.setOnRecyclerViewItemChildClickListener(new BaseQuickAdapter.OnRecyclerViewItemChildClickListener() { + mRecyclerView.addOnItemTouchListener(new OnItemChildClickListener( ) { @Override - public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { - String content = null; - Status status = (Status) adapter.getItem(position); - switch (view.getId()) { - case R.id.tweetAvatar: - content = "img:" + status.getUserAvatar(); - break; - case R.id.tweetName: - content = "name:" + status.getUserName(); - break; - } - Toast.makeText(AnimationUseActivity.this, content, Toast.LENGTH_LONG).show(); + public void SimpleOnItemChildClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + + } + }); +``` +#设置 it item long click +```java + mRecyclerView.addOnItemTouchListener(new OnItemLongClickListener( ) { + @Override + public void SimpleOnItemLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + + } + }); +``` +#设置 it item child long click +首先需要添加需要点击触发的 childview id +``` + @Override + protected void convert(BaseViewHolder helper, Status item) { + helper.setText(R.id.tweetName, item.getUserName()) + .setText(R.id.tweetText, item.getText()) + .setText(R.id.tweetDate, item.getCreatedAt()) + .setVisible(R.id.tweetRT, item.isRetweet()) + .addOnClickListener(R.id.tweetAvatar) + .addOnClickListener(R.id.tweetName) + .addOnLongClickListener(R.id.tweetText) + .linkify(R.id.tweetText); + Glide.with(mContext).load(item.getUserAvatar()).crossFade().placeholder(R.mipmap.def_head).transform(new GlideCircleTransform(mContext)).into((ImageView) helper.getView(R.id.tweetAvatar)); + } +``` +然后 +```java + mRecyclerView.addOnItemTouchListener(new OnItemChildLongClickListener( ) { + @Override + public void SimpleOnItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); } }); ``` +# 如果你想实现多种点击事件,你可以实现 SimpleClickListener类。提供了丰富的事件点击封装 +```java + mRecyclerView.addOnItemTouchListener(new SimpleClickListener() { + @Override + public void onItemClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + }); +``` + + #如何使用它添加动画? ![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/animation.gif) ```java @@ -261,6 +328,80 @@ mAdapter.enableSwipeItem(); mAdapter.setOnItemSwipeListener(onItemSwipeListener); ``` +#Expandable Item +![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/expandable_item.gif) +```Java +// 如果不想使用继承,可以只实现IExpandable接口 +// AbstractExpandableItem只是个帮助类 +public class Level0Item extends AbstractExpandableItem {...} +public class Level1Item extends AbstractExpandableItem {...} +public class Person {...} +``` +in adapter code +```Java + +public class ExpandableItemAdapter extends BaseMultiItemQuickAdapter { + public ExpandableItemAdapter(List data) { + super(data); + addItemType(TYPE_LEVEL_0, R.layout.item_expandable_lv0); + addItemType(TYPE_LEVEL_1, R.layout.item_expandable_lv1); + addItemType(TYPE_PERSON, R.layout.item_text_view); + } + @Override + protected void convert(final BaseViewHolder holder, final MultiItemEntity item) { + switch (holder.getItemViewType()) { + case TYPE_LEVEL_0: + .... + //set view content + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = holder.getAdapterPosition(); + if (lv0.isExpanded()) { + collapse(pos); + } else { + expand(pos); + } + }}); + break; + case TYPE_LEVEL_1: + // similar with level 0 + break; + case TYPE_PERSON: + //just set the content + break; + } +} +``` +In activity code +```Java +public class ExpandableUseActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + ... + ArrayList list = generateData(); + ExpandableItemAdapter adapter = new ExpandableItemAdapter(list); + mRecyclerView.setAdapter(adapter); + } + + private ArrayList generateData() { + ArrayList res = new ArrayList<>(); + for (int i = 0; i < lv0Count; i++) { + Level0Item lv0 = new Level0Item(...); + for (int j = 0; j < lv1Count; j++) { + Level1Item lv1 = new Level1Item(...); + for (int k = 0; k < personCount; k++) { + lv1.addSubItem(new Person()); + } + lv0.addSubItem(lv1); + } + res.add(lv0); + } + return res; + } +} +``` + >**持续更新!,所以推荐Star项目** #感谢 diff --git a/README.md b/README.md index bfe7e7359..b759f37ff 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-BaseRecyclerViewAdapterHelper-green.svg?style=true)](https://android-arsenal.com/details/1/3644) [![](https://jitpack.io/v/CymChad/BaseRecyclerViewAdapterHelper.svg)](https://jitpack.io/#CymChad/BaseRecyclerViewAdapterHelper) # BaseRecyclerViewAdapterHelper([中文版文档](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/README-cn.md)) -![Paste_Image.png](http://upload-images.jianshu.io/upload_images/972352-1d77e0a75a4a7c0a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) +![Paste_Image.png](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/develop/demo_res/logo.jpg) Powerful and flexible RecyclerAdapter -Please feel free to use this.(Love can be a **Star**) +Please feel free to use this.(Welcome to **Star** and **Fork**) ## Google Play Demo [![Get it on Google Play](https://developer.android.com/images/brand/en_generic_rgb_wo_60.png)](https://play.google.com/store/apps/details?id=com.chad.baserecyclerviewadapterhelper) @@ -18,6 +18,7 @@ Please feel free to use this.(Love can be a **Star**) - **custom item view type** - **add setEmptyView methods** - **add drag item** +- **Expandable Item** #Extension library [PinnedSectionItemDecoration](https://github.com/oubowu/PinnedSectionItemDecoration) @@ -59,41 +60,108 @@ public class QuickAdapter extends BaseQuickAdapter { ``` #Use it item click and item chlid click ![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/chlid_click.gif) +#Use it item click +Adapter ```java -mQuickAdapter.setOnRecyclerViewItemClickListener(new BaseQuickAdapter.OnRecyclerViewItemClickListener() { - @Override - public void onItemClick(View view, int position) { - //.. +mRecyclerView.addOnItemTouchListener(new OnItemClickListener( ){ + + @Override + public void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + + } + }); + +``` +#Use it item child click +first you should register child view id +``` + @Override + protected void convert(BaseViewHolder helper, Status item) { + helper.setText(R.id.tweetName, item.getUserName()) + .setText(R.id.tweetText, item.getText()) + .setText(R.id.tweetDate, item.getCreatedAt()) + .setVisible(R.id.tweetRT, item.isRetweet()) + .addOnClickListener(R.id.tweetAvatar) + .addOnClickListener(R.id.tweetName) + .addOnLongClickListener(R.id.tweetText) + .linkify(R.id.tweetText); + Glide.with(mContext).load(item.getUserAvatar()).crossFade().placeholder(R.mipmap.def_head).transform(new GlideCircleTransform(mContext)).into((ImageView) helper.getView(R.id.tweetAvatar)); } -}); ``` -#Use it item chlid click +and then + +```java + mRecyclerView.addOnItemTouchListener(new OnItemChildClickListener( ) { + @Override + public void SimpleOnItemChildClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + + } + }); +``` +#Use it item long click +```java + mRecyclerView.addOnItemTouchListener(new OnItemLongClickListener( ) { + @Override + public void SimpleOnItemLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + + } + }); +``` +#use it item child long click Adapter +``` + @Override + protected void convert(BaseViewHolder helper, Status item) { + helper.setText(R.id.tweetName, item.getUserName()) + .setText(R.id.tweetText, item.getText()) + .setText(R.id.tweetDate, item.getCreatedAt()) + .setVisible(R.id.tweetRT, item.isRetweet()) + .addOnClickListener(R.id.tweetAvatar) + .addOnClickListener(R.id.tweetName) + .addOnLongClickListener(R.id.tweetText) + .linkify(R.id.tweetText); + Glide.with(mContext).load(item.getUserAvatar()).crossFade().placeholder(R.mipmap.def_head).transform(new GlideCircleTransform(mContext)).into((ImageView) helper.getView(R.id.tweetAvatar)); + } +``` +Activity ```java -protected void convert(BaseViewHolder helper, Status item) { - helper.setOnClickListener(R.id.tweetAvatar, new OnItemChildClickListener()) - .setOnClickListener(R.id.tweetName, new OnItemChildClickListener()); -} + mRecyclerView.addOnItemTouchListener(new OnItemChildLongClickListener( ) { + @Override + public void SimpleOnItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + }); ``` +#if you wish to implement various forms of click Activity ```java -mQuickAdapter.setOnRecyclerViewItemChildClickListener(new BaseQuickAdapter.OnRecyclerViewItemChildClickListener() { + mRecyclerView.addOnItemTouchListener(new SimpleClickListener() { + @Override + public void onItemClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + @Override public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { - String content = null; - Status status = (Status) adapter.getItem(position); - switch (view.getId()) { - case R.id.tweetAvatar: - content = "img:" + status.getUserAvatar(); - break; - case R.id.tweetName: - content = "name:" + status.getUserName(); - break; - } - Toast.makeText(AnimationUseActivity.this, content, Toast.LENGTH_LONG).show(); + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); } }); -``` +``` + + #Use it add adaptar Animation ![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/animation.gif) @@ -259,6 +327,80 @@ mAdapter.enableSwipeItem(); mAdapter.setOnItemSwipeListener(onItemSwipeListener); ``` +#Expandable Item +![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/expandable_item.gif) +```Java +// if you don't want to extent a class, you can also use the interface IExpandable. +// AbstractExpandableItem is just a helper class. +public class Level0Item extends AbstractExpandableItem {...} +public class Level1Item extends AbstractExpandableItem {...} +public class Person {...} +``` +in adapter code +```Java + +public class ExpandableItemAdapter extends BaseMultiItemQuickAdapter { + public ExpandableItemAdapter(List data) { + super(data); + addItemType(TYPE_LEVEL_0, R.layout.item_expandable_lv0); + addItemType(TYPE_LEVEL_1, R.layout.item_expandable_lv1); + addItemType(TYPE_PERSON, R.layout.item_text_view); + } + @Override + protected void convert(final BaseViewHolder holder, final MultiItemEntity item) { + switch (holder.getItemViewType()) { + case TYPE_LEVEL_0: + .... + //set view content + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = holder.getAdapterPosition(); + if (lv0.isExpanded()) { + collapse(pos); + } else { + expand(pos); + } + }}); + break; + case TYPE_LEVEL_1: + // similar with level 0 + break; + case TYPE_PERSON: + //just set the content + break; + } +} +``` +In activity code +```Java +public class ExpandableUseActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + ... + ArrayList list = generateData(); + ExpandableItemAdapter adapter = new ExpandableItemAdapter(list); + mRecyclerView.setAdapter(adapter); + } + + private ArrayList generateData() { + ArrayList res = new ArrayList<>(); + for (int i = 0; i < lv0Count; i++) { + Level0Item lv0 = new Level0Item(...); + for (int j = 0; j < lv1Count; j++) { + Level1Item lv1 = new Level1Item(...); + for (int k = 0; k < personCount; k++) { + lv1.addSubItem(new Person()); + } + lv0.addSubItem(lv1); + } + res.add(lv0); + } + return res; + } +} +``` + #Thanks [JoanZapata / base-adapter-helper](https://github.com/JoanZapata/base-adapter-helper) diff --git a/app/build.gradle b/app/build.gradle index 527e2a50a..db3b5c61d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,7 +23,8 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile project(path: ':library') compile project(':material-spinner-1.0.5') - compile 'com.android.support:design:23.2.1' - compile 'com.android.support:cardview-v7:23.3.0' + compile 'com.android.support:design:23.4.0' + compile 'com.android.support:cardview-v7:23.4.0' compile 'com.github.bumptech.glide:glide:3.7.0' + compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b638d6a84..08038c84b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,6 +30,10 @@ + + + + diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/AnimationUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/AnimationUseActivity.java index cb443e818..374f53150 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/AnimationUseActivity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/AnimationUseActivity.java @@ -11,6 +11,7 @@ import com.chad.baserecyclerviewadapterhelper.animation.CustomAnimation; import com.chad.baserecyclerviewadapterhelper.entity.Status; import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemChildClickListener; import com.jaredrummler.materialspinner.MaterialSpinner; /** @@ -34,9 +35,9 @@ protected void onCreate(Bundle savedInstanceState) { private void initAdapter() { mQuickAdapter = new QuickAdapter(); mQuickAdapter.openLoadAnimation(); - mQuickAdapter.setOnRecyclerViewItemChildClickListener(new BaseQuickAdapter.OnRecyclerViewItemChildClickListener() { + mRecyclerView.addOnItemTouchListener(new OnItemChildClickListener() { @Override - public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { + public void SimpleOnItemChildClick(BaseQuickAdapter adapter, View view, int position) { String content = null; Status status = (Status) adapter.getItem(position); switch (view.getId()) { @@ -106,4 +107,4 @@ public void onItemSelected(MaterialSpinner view, int position, long id, String i }); } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ExpandableUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ExpandableUseActivity.java new file mode 100644 index 000000000..bd289e0ce --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ExpandableUseActivity.java @@ -0,0 +1,61 @@ +package com.chad.baserecyclerviewadapterhelper; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; + +import com.chad.baserecyclerviewadapterhelper.adapter.ExpandableItemAdapter; +import com.chad.baserecyclerviewadapterhelper.entity.Level0Item; +import com.chad.baserecyclerviewadapterhelper.entity.Level1Item; +import com.chad.baserecyclerviewadapterhelper.entity.Person; +import com.chad.library.adapter.base.entity.MultiItemEntity; + +import java.util.ArrayList; +import java.util.Random; + +/** + * Created by luoxw on 2016/8/9. + */ +public class ExpandableUseActivity extends Activity { + RecyclerView mRecyclerView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_expandable_item_use); + + mRecyclerView = (RecyclerView)findViewById(R.id.rv); + mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + + ArrayList list = generateData(); + ExpandableItemAdapter adapter = new ExpandableItemAdapter(list); + + mRecyclerView.setAdapter(adapter); + + + } + + private ArrayList generateData() { + int lv0Count = 9; + int lv1Count = 3; + int personCount = 5; + + String[] nameList = {"Bob", "Andy", "Lily", "Brown", "Bruce"}; + Random random = new Random(); + + ArrayList res = new ArrayList<>(); + for (int i = 0; i < lv0Count; i++) { + Level0Item lv0 = new Level0Item("This is " + i + "th item in Level 0", "subtitle of " + i); + for (int j = 0; j < lv1Count; j++) { + Level1Item lv1 = new Level1Item("Level 1 item: " + j, "just subtitle"); + for (int k = 0; k < personCount; k++) { + lv1.addSubItem(new Person(nameList[k], random.nextInt(40))); + } + lv0.addSubItem(lv1); + } + res.add(lv0); + } + return res; + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HeaderAndFooterUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HeaderAndFooterUseActivity.java index 1d427f072..c74e3df73 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HeaderAndFooterUseActivity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HeaderAndFooterUseActivity.java @@ -12,6 +12,7 @@ import com.chad.baserecyclerviewadapterhelper.adapter.QuickAdapter; import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; /** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper @@ -92,12 +93,13 @@ private void initAdapter() { mQuickAdapter = new QuickAdapter(PAGE_SIZE); mQuickAdapter.openLoadAnimation(); mRecyclerView.setAdapter(mQuickAdapter); - mQuickAdapter.setOnRecyclerViewItemClickListener(new BaseQuickAdapter.OnRecyclerViewItemClickListener() { + mRecyclerView.addOnItemTouchListener(new OnItemClickListener() { @Override - public void onItemClick(View view, int position) { + public void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) { Toast.makeText(HeaderAndFooterUseActivity.this, "" + Integer.toString(position), Toast.LENGTH_LONG).show(); } }); + } } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HomeActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HomeActivity.java index 642b209b9..ee8850b0b 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HomeActivity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HomeActivity.java @@ -6,11 +6,11 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; -import android.widget.Toast; import com.chad.baserecyclerviewadapterhelper.adapter.HomeAdapter; import com.chad.baserecyclerviewadapterhelper.entity.HomeItem; import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; import java.util.ArrayList; @@ -18,9 +18,9 @@ * https://github.com/CymChad/BaseRecyclerViewAdapterHelper */ public class HomeActivity extends Activity { - private static final Class[] ACTIVITY = {AnimationUseActivity.class, MultipleItemUseActivity.class, HeaderAndFooterUseActivity.class, PullToRefreshUseActivity.class, SectionUseActivity.class, EmptyViewUseActivity.class, ItemDragAndSwipeUseActivity.class}; - private static final String[] TITLE = {"Animation Use", "MultipleItem Use", "HeaderAndFooter Use", "PullToRefresh Use", "Section Use", "EmptyView Use", "ItemDragAndSwipe Use"}; - private static final String[] COLOR_STR = {"#0dddb8","#0bd4c3","#03cdcd","#00b1c5","#04b2d1","#04b2d1","#04b2d1"}; + private static final Class[] ACTIVITY = {AnimationUseActivity.class, MultipleItemUseActivity.class, HeaderAndFooterUseActivity.class, PullToRefreshUseActivity.class, SectionUseActivity.class, EmptyViewUseActivity.class, ItemDragAndSwipeUseActivity.class,RecyclerClickItemActivity.class, ExpandableUseActivity.class}; + private static final String[] TITLE = {"Animation Use", "MultipleItem Use", "HeaderAndFooter Use", "PullToRefresh Use", "Section Use", "EmptyView Use", "ItemDragAndSwipe Use","RecyclerClickItemActivity", "ExpandableItem Activity"}; + private static final String[] COLOR_STR = {"#0dddb8","#0bd4c3","#03cdcd","#00b1c5","#04b2d1","#04b2d1","#04b2d1","#04b2d1", "#04b2d1"}; private ArrayList mDataList; private RecyclerView mRecyclerView; @@ -31,22 +31,16 @@ protected void onCreate(Bundle savedInstanceState) { mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); initData(); - BaseQuickAdapter homeAdapter = new HomeAdapter( R.layout.home_item_view, mDataList); + BaseQuickAdapter homeAdapter = new HomeAdapter(R.layout.home_item_view, mDataList); homeAdapter.openLoadAnimation(); - homeAdapter.setOnRecyclerViewItemClickListener(new BaseQuickAdapter.OnRecyclerViewItemClickListener() { + mRecyclerView.addOnItemTouchListener(new OnItemClickListener() { @Override - public void onItemClick(View view, int position) { + public void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) { Intent intent = new Intent(HomeActivity.this, ACTIVITY[position]); startActivity(intent); } }); - homeAdapter.setOnRecyclerViewItemLongClickListener(new BaseQuickAdapter.OnRecyclerViewItemLongClickListener() { - @Override - public boolean onItemLongClick(View view, int position) { - Toast.makeText(HomeActivity.this,"onItemLongClick",Toast.LENGTH_LONG).show(); - return true; - } - }); + mRecyclerView.setAdapter(homeAdapter); } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MultipleItemUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MultipleItemUseActivity.java index 04363a2ca..72d3687cf 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MultipleItemUseActivity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MultipleItemUseActivity.java @@ -2,23 +2,48 @@ import android.app.Activity; import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.ViewGroup; import com.chad.baserecyclerviewadapterhelper.adapter.MultipleItemQuickAdapter; import com.chad.baserecyclerviewadapterhelper.data.DataServer; +import com.chad.baserecyclerviewadapterhelper.entity.MultipleItem; +import com.chad.library.adapter.base.BaseQuickAdapter; + +import java.util.List; + /** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper */ public class MultipleItemUseActivity extends Activity { private RecyclerView mRecyclerView; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_multiple_item_use); mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - MultipleItemQuickAdapter multipleItemAdapter = new MultipleItemQuickAdapter(this,DataServer.getMultipleItemData()); + final List data = DataServer.getMultipleItemData(); + final MultipleItemQuickAdapter multipleItemAdapter = new MultipleItemQuickAdapter(this, data); + final GridLayoutManager manager = new GridLayoutManager(this, 3); + multipleItemAdapter.addHeaderView(getView()); + mRecyclerView.setLayoutManager(manager); + multipleItemAdapter.setSpanSizeLookup(new BaseQuickAdapter.SpanSizeLookup() { + @Override + public int getSpanSize(GridLayoutManager gridLayoutManager, int position) { + return data.get(position).getSpanSize(); + } + }); mRecyclerView.setAdapter(multipleItemAdapter); } + + private View getView() { + View view = getLayoutInflater().inflate(R.layout.head_view, null); + view.findViewById(R.id.tv).setVisibility(View.GONE); + view.setLayoutParams(new DrawerLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + return view; + } } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/PullToRefreshUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/PullToRefreshUseActivity.java index 2992e6df4..d4a737225 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/PullToRefreshUseActivity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/PullToRefreshUseActivity.java @@ -4,8 +4,11 @@ import android.os.Bundle; import android.os.Handler; import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.StaggeredGridLayoutManager; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @@ -14,6 +17,7 @@ import com.chad.baserecyclerviewadapterhelper.adapter.QuickAdapter; import com.chad.baserecyclerviewadapterhelper.data.DataServer; import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; /** @@ -34,6 +38,8 @@ public class PullToRefreshUseActivity extends Activity implements BaseQuickAdapt private int mCurrentCounter = 0; + private boolean isErr; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -49,14 +55,14 @@ protected void onCreate(Bundle savedInstanceState) { private void addHeadView() { View headView = getLayoutInflater().inflate(R.layout.head_view, (ViewGroup) mRecyclerView.getParent(), false); - ((TextView)headView.findViewById(R.id.tv)).setText("click use custom loading view"); + ((TextView) headView.findViewById(R.id.tv)).setText("click use custom loading view"); final View customLoading = getLayoutInflater().inflate(R.layout.custom_loading, (ViewGroup) mRecyclerView.getParent(), false); headView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mQuickAdapter.setLoadingView(customLoading); mRecyclerView.setAdapter(mQuickAdapter); - Toast.makeText(PullToRefreshUseActivity.this,"use ok!",Toast.LENGTH_LONG).show(); + Toast.makeText(PullToRefreshUseActivity.this, "use ok!", Toast.LENGTH_LONG).show(); } }); mQuickAdapter.addHeaderView(headView); @@ -68,19 +74,26 @@ public void onLoadMoreRequested() { @Override public void run() { if (mCurrentCounter >= TOTAL_COUNTER) { - mQuickAdapter.notifyDataChangedAfterLoadMore(false); + mQuickAdapter.loadComplete(); if (notLoadingView == null) { notLoadingView = getLayoutInflater().inflate(R.layout.not_loading, (ViewGroup) mRecyclerView.getParent(), false); } mQuickAdapter.addFooterView(notLoadingView); } else { - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - mQuickAdapter.notifyDataChangedAfterLoadMore(DataServer.getSampleData(PAGE_SIZE), true); - mCurrentCounter = mQuickAdapter.getData().size(); - } - }, delayMillis); + if (isErr) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + mQuickAdapter.addData(DataServer.getSampleData(PAGE_SIZE)); + mCurrentCounter = mQuickAdapter.getData().size(); + } + }, delayMillis); + } else { + isErr = true; + Toast.makeText(PullToRefreshUseActivity.this, R.string.network_err, Toast.LENGTH_LONG).show(); + mQuickAdapter.showLoadMoreFailedView(); + + } } } @@ -93,10 +106,11 @@ public void onRefresh() { @Override public void run() { mQuickAdapter.setNewData(DataServer.getSampleData(PAGE_SIZE)); - mQuickAdapter.openLoadMore(PAGE_SIZE, true); + mQuickAdapter.openLoadMore(PAGE_SIZE); mQuickAdapter.removeAllFooterView(); mCurrentCounter = PAGE_SIZE; mSwipeRefreshLayout.setRefreshing(false); + isErr = false; } }, delayMillis); } @@ -107,12 +121,14 @@ private void initAdapter() { mRecyclerView.setAdapter(mQuickAdapter); mCurrentCounter = mQuickAdapter.getData().size(); mQuickAdapter.setOnLoadMoreListener(this); - mQuickAdapter.openLoadMore(PAGE_SIZE, true);//or call mQuickAdapter.setPageSize(PAGE_SIZE); mQuickAdapter.openLoadMore(true); - mQuickAdapter.setOnRecyclerViewItemClickListener(new BaseQuickAdapter.OnRecyclerViewItemClickListener() { + + mRecyclerView.addOnItemTouchListener(new OnItemClickListener() { @Override - public void onItemClick(View view, int position) { + public void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) { Toast.makeText(PullToRefreshUseActivity.this, Integer.toString(position), Toast.LENGTH_LONG).show(); } }); } + + } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/RecyclerClickItemActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/RecyclerClickItemActivity.java new file mode 100644 index 000000000..62043b40e --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/RecyclerClickItemActivity.java @@ -0,0 +1,162 @@ +package com.chad.baserecyclerviewadapterhelper; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListView; +import android.widget.Toast; + +import com.chad.baserecyclerviewadapterhelper.adapter.QuickClickAdapter; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; + +/** + * create by AllenCoder + */ +public class RecyclerClickItemActivity extends Activity { + + private RecyclerView mRecyclerView; + private QuickClickAdapter mQuickAdapter; + private static final int PAGE_SIZE = 10; + private static String TAG = "RecyclerClickItemActivity"; + private ListView mListView; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_header_and_footer_use); + mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); + mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + initAdapter(); + mQuickAdapter.addHeaderView(getHeadView()); + mQuickAdapter.addFooterView(getFootView()); + mRecyclerView.setAdapter(mQuickAdapter); + + /** + * Item clcik + */ + + mRecyclerView.addOnItemTouchListener(new OnItemClickListener() { + + @Override + public void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { + super.onItemChildClick(adapter, view, position); + switch (view.getId()) { + case R.id.tweetAvatar: + Toast.makeText(RecyclerClickItemActivity.this, "The " + Integer.toString(position)+" tweetAvatar is clicked", Toast.LENGTH_SHORT).show(); + break; + case R.id.tweetName: + Toast.makeText(RecyclerClickItemActivity.this, "The " + Integer.toString(position)+" tweetName is clicked", Toast.LENGTH_SHORT).show(); + break; + default: + break; + } + } + + + @Override + public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) { + super.onItemLongClick(adapter, view, position); + Toast.makeText(RecyclerClickItemActivity.this,"The " + Integer.toString(position)+ " Item is LongClick ", Toast.LENGTH_SHORT).show(); + + } + + @Override + public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + super.onItemChildLongClick(adapter, view, position); + Toast.makeText(RecyclerClickItemActivity.this, "The "+ Integer.toString(position)+" view itemchild " + "is LongClick " + Integer.toString(position), Toast.LENGTH_SHORT).show(); + + } + }); + /** + * this is sample code + */ + /* mRecyclerView.addOnItemTouchListener(new OnItemChildClickListener() { + @Override + public void SimpleOnItemChildClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + + } + }); + + mRecyclerView.addOnItemTouchListener(new OnItemLongClickListener() { + @Override + public void SimpleOnItemLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + + } + }); + mRecyclerView.addOnItemTouchListener(new OnItemChildLongClickListener() { + @Override + public void SimpleOnItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + }); + mRecyclerView.addOnItemTouchListener(new SimpleClickListener() { + @Override + public void onItemClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); + } + });*/ + } + + private View getHeadView() { + View view = getLayoutInflater().inflate(R.layout.head_view, null); + view.findViewById(R.id.tv).setVisibility(View.GONE); + view.setLayoutParams(new DrawerLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Toast.makeText(RecyclerClickItemActivity.this, "click headView", Toast.LENGTH_LONG).show(); + } + }); + return view; + } + private View getFootView() { + View view = getLayoutInflater().inflate(R.layout.head_view, null); + view.findViewById(R.id.tv).setVisibility(View.GONE); + view.setLayoutParams(new DrawerLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Toast.makeText(RecyclerClickItemActivity.this, "click FootView", Toast.LENGTH_LONG).show(); + } + }); + return view; + } + private void initAdapter() { + mQuickAdapter = new QuickClickAdapter(PAGE_SIZE); + mQuickAdapter.openLoadAnimation(); + mRecyclerView.setAdapter(mQuickAdapter); + } + + + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + return super.dispatchTouchEvent(ev); + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java index d9e9ae895..3287cb0b1 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java @@ -11,13 +11,14 @@ import com.chad.baserecyclerviewadapterhelper.data.DataServer; import com.chad.baserecyclerviewadapterhelper.entity.MySection; import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; import java.util.List; /** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper */ -public class SectionUseActivity extends Activity implements BaseQuickAdapter.OnRecyclerViewItemClickListener { +public class SectionUseActivity extends Activity { private RecyclerView mRecyclerView; private List mData; @@ -29,22 +30,26 @@ protected void onCreate(Bundle savedInstanceState) { mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)); mData = DataServer.getSampleData(); SectionAdapter sectionAdapter = new SectionAdapter(R.layout.item_section_content, R.layout.def_section_head, mData); - sectionAdapter.setOnRecyclerViewItemClickListener(this); - sectionAdapter.setOnRecyclerViewItemChildClickListener(new BaseQuickAdapter.OnRecyclerViewItemChildClickListener() { + mRecyclerView.addOnItemTouchListener(new OnItemClickListener() { + + @Override + public void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) { + MySection mySection = mData.get(position); + if (mySection.isHeader) + Toast.makeText(SectionUseActivity.this, mySection.header, Toast.LENGTH_LONG).show(); + else + Toast.makeText(SectionUseActivity.this, mySection.t.getName(), Toast.LENGTH_LONG).show(); + } + @Override public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(SectionUseActivity.this, "onItemChildClick", Toast.LENGTH_LONG).show(); + Toast.makeText(SectionUseActivity.this, "onItemChildClick" + position, Toast.LENGTH_LONG).show(); } + + }); mRecyclerView.setAdapter(sectionAdapter); } - @Override - public void onItemClick(View view, int position) { - MySection mySection = mData.get(position); - if (mySection.isHeader) - Toast.makeText(this, mySection.header, Toast.LENGTH_LONG).show(); - else - Toast.makeText(this, mySection.t.getName(), Toast.LENGTH_LONG).show(); - } + } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ExpandableItemAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ExpandableItemAdapter.java new file mode 100644 index 000000000..d0934a254 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ExpandableItemAdapter.java @@ -0,0 +1,90 @@ +package com.chad.baserecyclerviewadapterhelper.adapter; + +import android.util.Log; +import android.view.View; + +import com.chad.baserecyclerviewadapterhelper.R; +import com.chad.baserecyclerviewadapterhelper.entity.Level0Item; +import com.chad.baserecyclerviewadapterhelper.entity.Level1Item; +import com.chad.baserecyclerviewadapterhelper.entity.Person; +import com.chad.library.adapter.base.BaseMultiItemQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; +import com.chad.library.adapter.base.entity.MultiItemEntity; + +import java.util.List; + +/** + * Created by luoxw on 2016/8/9. + */ +public class ExpandableItemAdapter extends BaseMultiItemQuickAdapter { + private static final String TAG = ExpandableItemAdapter.class.getSimpleName(); + + public static final int TYPE_LEVEL_0 = 0; + public static final int TYPE_LEVEL_1 = 1; + public static final int TYPE_PERSON = 2; + + /** + * Same as QuickAdapter#QuickAdapter(Context,int) but with + * some initialization data. + * + * @param data A new list is created out of this one to avoid mutable list + */ + public ExpandableItemAdapter(List data) { + super(data); + addItemType(TYPE_LEVEL_0, R.layout.item_expandable_lv0); + addItemType(TYPE_LEVEL_1, R.layout.item_expandable_lv1); + addItemType(TYPE_PERSON, R.layout.item_text_view); + } + + @Override + protected void convert(final BaseViewHolder holder, final MultiItemEntity item) { + switch (holder.getItemViewType()) { + case TYPE_LEVEL_0: + final Level0Item lv0 = (Level0Item)item; + holder.setText(R.id.title, lv0.title) + .setText(R.id.sub_title, lv0.subTitle) + .setText(R.id.expand_state, lv0.isExpanded() ? R.string.expanded : R.string.collapsed); + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = holder.getAdapterPosition(); + Log.d(TAG, "Level 0 item pos: " + pos); + if (lv0.isExpanded()) { + collapse(pos); + } else { + expand(pos); + } + } + }); + break; + case TYPE_LEVEL_1: + final Level1Item lv1 = (Level1Item)item; + holder.setText(R.id.title, lv1.title) + .setText(R.id.sub_title, lv1.subTitle) + .setText(R.id.expand_state, lv1.isExpanded() ? R.string.expanded : R.string.collapsed); + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = holder.getAdapterPosition(); + Log.d(TAG, "Level 1 item pos: " + pos); + if (lv1.isExpanded()) { + collapse(pos); + } else { + expand(pos); + } + } + }); + break; + case TYPE_PERSON: + final Person person = (Person)item; + holder.setText(R.id.tv, person.name); + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "person: " + person.name + " age: " + person.age); + } + }); + break; + } + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/MultipleItemQuickAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/MultipleItemQuickAdapter.java index 2145fb05d..6907c049a 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/MultipleItemQuickAdapter.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/MultipleItemQuickAdapter.java @@ -15,10 +15,9 @@ public class MultipleItemQuickAdapter extends BaseMultiItemQuickAdapter { public MultipleItemQuickAdapter(Context context, List data) { - super( data); + super(data); addItemType(MultipleItem.TEXT, R.layout.item_text_view); addItemType(MultipleItem.IMG, R.layout.item_image_view); - addItemType(MultipleItem.IMGS, R.layout.item_image_views); } @Override @@ -30,9 +29,6 @@ protected void convert(BaseViewHolder helper, MultipleItem item) { case MultipleItem.IMG: // set img data break; - case MultipleItem.IMGS: - // set imgs data - break; } } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickAdapter.java index d19d5518c..34b9e4881 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickAdapter.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickAdapter.java @@ -28,8 +28,8 @@ protected void convert(BaseViewHolder helper, Status item) { .setText(R.id.tweetText, item.getText()) .setText(R.id.tweetDate, item.getCreatedAt()) .setVisible(R.id.tweetRT, item.isRetweet()) - .setOnClickListener(R.id.tweetAvatar, new OnItemChildClickListener()) - .setOnClickListener(R.id.tweetName, new OnItemChildClickListener()) + .addOnClickListener(R.id.tweetAvatar) + .addOnClickListener(R.id.tweetName) .linkify(R.id.tweetText); Glide.with(mContext).load(item.getUserAvatar()).crossFade().placeholder(R.mipmap.def_head).transform(new GlideCircleTransform(mContext)).into((ImageView) helper.getView(R.id.tweetAvatar)); diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickClickAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickClickAdapter.java new file mode 100644 index 000000000..6d2e1b73a --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickClickAdapter.java @@ -0,0 +1,39 @@ +package com.chad.baserecyclerviewadapterhelper.adapter; + +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.chad.baserecyclerviewadapterhelper.R; +import com.chad.baserecyclerviewadapterhelper.data.DataServer; +import com.chad.baserecyclerviewadapterhelper.entity.Status; +import com.chad.baserecyclerviewadapterhelper.transform.GlideCircleTransform; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; + +/** + * https://github.com/CymChad/BaseRecyclerViewAdapterHelper + */ +public class QuickClickAdapter extends BaseQuickAdapter { + public QuickClickAdapter() { + super( R.layout.tweet, DataServer.getSampleData(100)); + } + + public QuickClickAdapter(int dataSize) { + super( R.layout.tweet, DataServer.getSampleData(dataSize)); + } + + @Override + protected void convert(BaseViewHolder helper, Status item) { + helper.setText(R.id.tweetName, item.getUserName()) + .setText(R.id.tweetText, item.getText()) + .setText(R.id.tweetDate, item.getCreatedAt()) + .setVisible(R.id.tweetRT, item.isRetweet()) + .addOnClickListener(R.id.tweetAvatar) + .addOnClickListener(R.id.tweetName) + .addOnLongClickListener(R.id.tweetText) + .linkify(R.id.tweetText); + Glide.with(mContext).load(item.getUserAvatar()).crossFade().placeholder(R.mipmap.def_head).transform(new GlideCircleTransform(mContext)).into((ImageView) helper.getView(R.id.tweetAvatar)); + } + + +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/SectionAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/SectionAdapter.java index d6ea1c91e..1c382d2d4 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/SectionAdapter.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/SectionAdapter.java @@ -5,6 +5,7 @@ import com.chad.baserecyclerviewadapterhelper.entity.Video; import com.chad.library.adapter.base.BaseSectionQuickAdapter; import com.chad.library.adapter.base.BaseViewHolder; +import com.chad.library.adapter.base.listener.OnItemChildClickListener; import java.util.List; @@ -28,7 +29,7 @@ public SectionAdapter( int layoutResId, int sectionHeadResId, List data) { protected void convertHead(BaseViewHolder helper,final MySection item) { helper.setText(R.id.header, item.header); helper.setVisible(R.id.more,item.isMore()); - helper.setOnClickListener(R.id.more,new OnItemChildClickListener()); + helper.addOnClickListener(R.id.more); } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.java index 7d0a33992..06580eb58 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.java @@ -85,19 +85,14 @@ public static List getStrData() { public static List getMultipleItemData() { List list = new ArrayList<>(); - for (int i = 0; i < 20; i++) { - MultipleItem multipleItem = new MultipleItem(); - String str = null; - multipleItem.setItemType(MultipleItem.IMG); - if (i % 2 == 0) { - str = CYM_CHAD; - multipleItem.setItemType(MultipleItem.TEXT); - } else if (i % 3 == 0) { - multipleItem.setItemType(MultipleItem.IMGS); - } - multipleItem.setContent(str); - list.add(multipleItem); + for (int i = 0; i <= 4; i++) { + list.add(new MultipleItem(MultipleItem.TEXT, MultipleItem.TEXT_SPAN_SIZE, CYM_CHAD)); + list.add(new MultipleItem(MultipleItem.IMG, MultipleItem.BIG_IMG_SPAN_SIZE)); + list.add(new MultipleItem(MultipleItem.IMG, MultipleItem.IMG_SPAN_SIZE)); + list.add(new MultipleItem(MultipleItem.IMG, MultipleItem.IMG_SPAN_SIZE)); + list.add(new MultipleItem(MultipleItem.IMG, MultipleItem.IMG_SPAN_SIZE)); } + return list; } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level0Item.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level0Item.java new file mode 100644 index 000000000..49a3f9102 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level0Item.java @@ -0,0 +1,23 @@ +package com.chad.baserecyclerviewadapterhelper.entity; + +import com.chad.library.adapter.base.entity.AbstractExpandableItem; +import com.chad.baserecyclerviewadapterhelper.adapter.ExpandableItemAdapter; +import com.chad.library.adapter.base.entity.MultiItemEntity; + +/** + * Created by luoxw on 2016/8/10. + */ +public class Level0Item extends AbstractExpandableItem implements MultiItemEntity { + public String title; + public String subTitle; + + public Level0Item( String title, String subTitle) { + this.subTitle = subTitle; + this.title = title; + } + + @Override + public int getItemType() { + return ExpandableItemAdapter.TYPE_LEVEL_0; + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level1Item.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level1Item.java new file mode 100644 index 000000000..e5cd8eb1f --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level1Item.java @@ -0,0 +1,24 @@ +package com.chad.baserecyclerviewadapterhelper.entity; + +import com.chad.library.adapter.base.entity.AbstractExpandableItem; +import com.chad.baserecyclerviewadapterhelper.adapter.ExpandableItemAdapter; +import com.chad.library.adapter.base.entity.MultiItemEntity; + +/** + * Created by luoxw on 2016/8/10. + */ + +public class Level1Item extends AbstractExpandableItem implements MultiItemEntity{ + public String title; + public String subTitle; + + public Level1Item(String title, String subTitle) { + this.subTitle = subTitle; + this.title = title; + } + + @Override + public int getItemType() { + return ExpandableItemAdapter.TYPE_LEVEL_1; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MultipleItem.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MultipleItem.java index 0f5079324..06762f75c 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MultipleItem.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MultipleItem.java @@ -5,10 +5,33 @@ /** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper */ -public class MultipleItem extends MultiItemEntity { +public class MultipleItem implements MultiItemEntity { public static final int TEXT = 1; public static final int IMG = 2; - public static final int IMGS = 3; + public static final int BIG_IMG_SPAN_SIZE = 3; + public static final int TEXT_SPAN_SIZE = 3; + public static final int IMG_SPAN_SIZE = 1; + private int itemType; + private int spanSize; + + public MultipleItem(int itemType, int spanSize, String content) { + this.itemType = itemType; + this.spanSize = spanSize; + this.content = content; + } + + public MultipleItem(int itemType, int spanSize) { + this.itemType = itemType; + this.spanSize = spanSize; + } + + public int getSpanSize() { + return spanSize; + } + + public void setSpanSize(int spanSize) { + this.spanSize = spanSize; + } private String content; @@ -19,4 +42,9 @@ public String getContent() { public void setContent(String content) { this.content = content; } + + @Override + public int getItemType() { + return itemType; + } } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Person.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Person.java new file mode 100644 index 000000000..002d05e4c --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Person.java @@ -0,0 +1,23 @@ +package com.chad.baserecyclerviewadapterhelper.entity; + +import com.chad.baserecyclerviewadapterhelper.adapter.ExpandableItemAdapter; +import com.chad.library.adapter.base.entity.MultiItemEntity; + +/** + * Created by luoxw on 2016/8/10. + */ + +public class Person implements MultiItemEntity{ + public Person(String name, int age) { + this.age = age; + this.name = name; + } + + public String name; + public int age; + + @Override + public int getItemType() { + return ExpandableItemAdapter.TYPE_PERSON; + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_expandable_item_use.xml b/app/src/main/res/layout/activity_expandable_item_use.xml new file mode 100644 index 000000000..62130507f --- /dev/null +++ b/app/src/main/res/layout/activity_expandable_item_use.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_expandable_lv0.xml b/app/src/main/res/layout/item_expandable_lv0.xml new file mode 100644 index 000000000..95e8befaf --- /dev/null +++ b/app/src/main/res/layout/item_expandable_lv0.xml @@ -0,0 +1,34 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_expandable_lv1.xml b/app/src/main/res/layout/item_expandable_lv1.xml new file mode 100644 index 000000000..0ecf3f27b --- /dev/null +++ b/app/src/main/res/layout/item_expandable_lv1.xml @@ -0,0 +1,34 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_image_views.xml b/app/src/main/res/layout/item_image_views.xml index 74cf28ab3..beee3fb72 100644 --- a/app/src/main/res/layout/item_image_views.xml +++ b/app/src/main/res/layout/item_image_views.xml @@ -45,4 +45,4 @@ android:layout_gravity="center" android:src="@mipmap/biglogo_gray"/> - \ No newline at end of file + diff --git a/app/src/main/res/layout/tweet.xml b/app/src/main/res/layout/tweet.xml index 08cf86fa4..4b4571eb8 100755 --- a/app/src/main/res/layout/tweet.xml +++ b/app/src/main/res/layout/tweet.xml @@ -67,4 +67,4 @@ android:text="04/06/13"/> - \ No newline at end of file + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6bd0b07cc..27512c587 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,4 +2,7 @@ BaseRecyclerViewAdapterHelper HeaderAndFooterUseActivity There is no data + expanded + collapsed + Simulation network error diff --git a/demo_res/expandable_item.gif b/demo_res/expandable_item.gif new file mode 100644 index 000000000..ffeb62073 Binary files /dev/null and b/demo_res/expandable_item.gif differ diff --git a/demo_res/logo.jpg b/demo_res/logo.jpg new file mode 100644 index 000000000..2349578bc Binary files /dev/null and b/demo_res/logo.jpg differ diff --git a/demo_res/multiple_demo.png b/demo_res/multiple_demo.png new file mode 100644 index 000000000..18ae4d546 Binary files /dev/null and b/demo_res/multiple_demo.png differ diff --git a/library/src/main/java/com/chad/library/adapter/base/BaseMultiItemQuickAdapter.java b/library/src/main/java/com/chad/library/adapter/base/BaseMultiItemQuickAdapter.java index 87ad33212..e466c711d 100644 --- a/library/src/main/java/com/chad/library/adapter/base/BaseMultiItemQuickAdapter.java +++ b/library/src/main/java/com/chad/library/adapter/base/BaseMultiItemQuickAdapter.java @@ -1,5 +1,6 @@ package com.chad.library.adapter.base; +import android.support.annotation.LayoutRes; import android.util.SparseArray; import android.view.ViewGroup; @@ -17,6 +18,8 @@ public abstract class BaseMultiItemQuickAdapter exten */ private SparseArray layouts; + private static final int DEFAULT_VIEW_TYPE = -0xff; + /** * Same as QuickAdapter#QuickAdapter(Context,int) but with * some initialization data. @@ -29,9 +32,16 @@ public BaseMultiItemQuickAdapter( List data) { @Override protected int getDefItemViewType(int position) { - return ((MultiItemEntity) mData.get(position)).getItemType(); + Object item = mData.get(position); + if (item instanceof MultiItemEntity) { + return ((MultiItemEntity)item).getItemType(); + } + return DEFAULT_VIEW_TYPE; } + protected void setDefaultViewTypeLayout(@LayoutRes int layoutResId) { + addItemType(DEFAULT_VIEW_TYPE, layoutResId); + } @Override protected BaseViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) { @@ -42,7 +52,7 @@ private int getLayoutId(int viewType) { return layouts.get(viewType); } - protected void addItemType(int type, int layoutResId) { + protected void addItemType(int type, @LayoutRes int layoutResId) { if (layouts == null) { layouts = new SparseArray<>(); } diff --git a/library/src/main/java/com/chad/library/adapter/base/BaseQuickAdapter.java b/library/src/main/java/com/chad/library/adapter/base/BaseQuickAdapter.java index 20a92aeac..f428b952c 100755 --- a/library/src/main/java/com/chad/library/adapter/base/BaseQuickAdapter.java +++ b/library/src/main/java/com/chad/library/adapter/base/BaseQuickAdapter.java @@ -1,12 +1,12 @@ /** * Copyright 2013 Joan Zapata - * + *

* 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 - * + *

+ * 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. @@ -18,10 +18,14 @@ import android.animation.Animator; import android.content.Context; import android.support.annotation.IntDef; +import android.support.annotation.IntRange; +import android.support.annotation.NonNull; import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.LayoutParams; import android.support.v7.widget.StaggeredGridLayoutManager; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -36,6 +40,7 @@ import com.chad.library.adapter.base.animation.SlideInBottomAnimation; import com.chad.library.adapter.base.animation.SlideInLeftAnimation; import com.chad.library.adapter.base.animation.SlideInRightAnimation; +import com.chad.library.adapter.base.entity.IExpandable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -61,8 +66,6 @@ public abstract class BaseQuickAdapter extends RecyclerView.Adapter extends RecyclerView.Adapter extends RecyclerView.Adapter data) { mNextLoadEnable = true; // mFooterLayout = null; } + if (loadMoreFailedView != null) { + removeFooterView(loadMoreFailedView); + } mLastPosition = -1; notifyDataSetChanged(); } @@ -359,10 +224,13 @@ public void setNewData(List data) { /** * additional data; * - * @param data + * @param newData */ - public void addData(List data) { - this.mData.addAll(data); + public void addData(List newData) { + this.mData.addAll(newData); + if (mNextLoadEnable) { + mLoadingMoreEnable = false; + } notifyDataSetChanged(); } @@ -564,7 +432,6 @@ public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { break; default: baseViewHolder = onCreateDefViewHolder(parent, viewType); - initItemClickListener(baseViewHolder); } return baseViewHolder; @@ -612,7 +479,7 @@ protected void setFullSpan(RecyclerView.ViewHolder holder) { } @Override - public void onAttachedToRecyclerView(RecyclerView recyclerView) { + public void onAttachedToRecyclerView(final RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if (manager instanceof GridLayoutManager) { @@ -621,10 +488,38 @@ public void onAttachedToRecyclerView(RecyclerView recyclerView) { @Override public int getSpanSize(int position) { int type = getItemViewType(position); - return (type == EMPTY_VIEW || type == HEADER_VIEW || type == FOOTER_VIEW || type == LOADING_VIEW) ? gridManager.getSpanCount() : 1; + if (mSpanSizeLookup == null) + return (type == EMPTY_VIEW || type == HEADER_VIEW || type == FOOTER_VIEW || type == LOADING_VIEW) ? gridManager.getSpanCount() : 1; + else + return (type == EMPTY_VIEW || type == HEADER_VIEW || type == FOOTER_VIEW || type == LOADING_VIEW) ? gridManager.getSpanCount() : mSpanSizeLookup.getSpanSize(gridManager, position - getHeaderLayoutCount()); } }); } + recyclerView.post(new Runnable() { + @Override + public void run() { + if (mRequestLoadMoreListener != null && pageSize == -1) { + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + int visibleItemCount = layoutManager.getChildCount(); + openLoadMore(visibleItemCount); + } + } + }); + + } + + private boolean flag = true; + private SpanSizeLookup mSpanSizeLookup; + + public interface SpanSizeLookup { + int getSpanSize(GridLayoutManager gridLayoutManager, int position); + } + + /** + * @param spanSizeLookup instance to be used to query number of spans occupied by each item + */ + public void setSpanSizeLookup(SpanSizeLookup spanSizeLookup) { + this.mSpanSizeLookup = spanSizeLookup; } /** @@ -807,6 +702,38 @@ public void removeAllFooterView() { mFooterLayout = null; } + /** + * Set the view to show when load more failed. + */ + public void setLoadMoreFailedView(View view) { + loadMoreFailedView = view; + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + removeFooterView(loadMoreFailedView); + openLoadMore(pageSize); + } + }); + } + + /** + * Call this method when load more failed. + */ + public void showLoadMoreFailedView() { + loadComplete(); + if (loadMoreFailedView == null) { + loadMoreFailedView = mLayoutInflater.inflate(R.layout.def_load_more_failed, null); + loadMoreFailedView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + removeFooterView(loadMoreFailedView); + openLoadMore(pageSize); + } + }); + } + addFooterView(loadMoreFailedView); + } + /** * Sets the view to show if the adapter is empty */ @@ -847,42 +774,17 @@ public View getEmptyView() { return mEmptyView; } - /** - * see more {@link public void notifyDataChangedAfterLoadMore(boolean isNextLoad)} - * - * @param isNextLoad - */ - @Deprecated - public void isNextLoad(boolean isNextLoad) { - mNextLoadEnable = isNextLoad; - mLoadingMoreEnable = false; - notifyDataSetChanged(); - - } /** - * @param isNextLoad true - * if true when loading more data can show loadingView + * */ - public void notifyDataChangedAfterLoadMore(boolean isNextLoad) { - mNextLoadEnable = isNextLoad; + public void loadComplete() { + mNextLoadEnable = false; mLoadingMoreEnable = false; notifyDataSetChanged(); } - /** - * add more data - * - * @param data - * @param isNextLoad - */ - public void notifyDataChangedAfterLoadMore(List data, boolean isNextLoad) { - mData.addAll(data); - notifyDataChangedAfterLoadMore(isNextLoad); - - } - private void addLoadMore(RecyclerView.ViewHolder holder) { if (isLoadMore() && !mLoadingMoreEnable) { @@ -891,29 +793,6 @@ private void addLoadMore(RecyclerView.ViewHolder holder) { } } - /** - * init the baseViewHolder to register onRecyclerViewItemClickListener and onRecyclerViewItemLongClickListener - * - * @param baseViewHolder - */ - private void initItemClickListener(final BaseViewHolder baseViewHolder) { - if (onRecyclerViewItemClickListener != null) { - baseViewHolder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onRecyclerViewItemClickListener.onItemClick(v, baseViewHolder.getLayoutPosition() - getHeaderLayoutCount()); - } - }); - } - if (onRecyclerViewItemLongClickListener != null) { - baseViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - return onRecyclerViewItemLongClickListener.onItemLongClick(v, baseViewHolder.getLayoutPosition() - getHeaderLayoutCount()); - } - }); - } - } /** * add animation when you want to show time @@ -981,6 +860,7 @@ protected void onBindDefViewHolder(BaseViewHolder holder, T item) { public interface RequestLoadMoreListener { void onLoadMoreRequested(); + } @@ -1058,4 +938,108 @@ public long getItemId(int position) { return position; } + private int recursiveExpand(int position, @NonNull List list) { + int count = 0; + int pos = position + list.size() - 1; + for (int i = list.size() - 1; i >= 0; i--, pos--) { + if (list.get(i) instanceof IExpandable) { + IExpandable item = (IExpandable) list.get(i); + if (item.isExpanded() && hasSubItems(item)) { + List subList = item.getSubItems(); + mData.addAll(pos + 1, subList); + int subItemCount = recursiveExpand(pos + 1, subList); + count += subItemCount; + } + } + } + return count; + + } + + /** + * Expand an expandable item + * + * @param position position of the item + * @return the number of items that have been added. + */ + public int expand(@IntRange(from = 0) int position) { + T item = getItem(position); + if (!isExpandable(item)) { + return 0; + } + + IExpandable expandable = (IExpandable) item; + if (!hasSubItems(expandable)) { + expandable.setExpanded(false); + return 0; + } + int subItemCount = 0; + if (!expandable.isExpanded()) { + List list = expandable.getSubItems(); + mData.addAll(position + 1, list); + subItemCount += recursiveExpand(position + 1, list); + + expandable.setExpanded(true); + subItemCount += list.size(); + } + notifyItemRangeInserted(position + 1, subItemCount); + return subItemCount; + } + + private int recursiveCollapse(@IntRange(from = 0) int position) { + T item = getItem(position); + if (!isExpandable(item)) { + return 0; + } + IExpandable expandable = (IExpandable) item; + int subItemCount = 0; + if (expandable.isExpanded()) { + List subItems = expandable.getSubItems(); + for (int i = subItems.size() - 1; i >= 0; i--) { + T subItem = subItems.get(i); + int pos = getItemPosition(subItem); + if (pos < 0) { + continue; + } + if (subItem instanceof IExpandable) { + subItemCount += recursiveCollapse(pos); + } + mData.remove(pos); + subItemCount++; + } + } + return subItemCount; + } + + /** + * Collapse an expandable item that has been expanded.. + * + * @param position the position of the item + * @return the number of subItems collapsed. + */ + public int collapse(@IntRange(from = 0) int position) { + T item = getItem(position); + if (!isExpandable(item)) { + return 0; + } + IExpandable expandable = (IExpandable) item; + int subItemCount = recursiveCollapse(position); + expandable.setExpanded(false); + notifyItemRangeRemoved(position + 1, subItemCount); + return subItemCount; + } + + private int getItemPosition(T item) { + return item != null && mData != null && !mData.isEmpty() ? mData.indexOf(item) : -1; + } + + private boolean hasSubItems(IExpandable item) { + List list = item.getSubItems(); + return list != null && list.size() > 0; + } + + private boolean isExpandable(T item) { + return item != null && item instanceof IExpandable; + } + } diff --git a/library/src/main/java/com/chad/library/adapter/base/BaseViewHolder.java b/library/src/main/java/com/chad/library/adapter/base/BaseViewHolder.java index 1b4cbf81d..a03e3228a 100755 --- a/library/src/main/java/com/chad/library/adapter/base/BaseViewHolder.java +++ b/library/src/main/java/com/chad/library/adapter/base/BaseViewHolder.java @@ -20,6 +20,8 @@ import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Build; +import android.support.annotation.DrawableRes; +import android.support.annotation.StringRes; import android.support.v7.widget.RecyclerView; import android.text.util.Linkify; import android.util.SparseArray; @@ -34,6 +36,8 @@ import android.widget.RatingBar; import android.widget.TextView; +import java.util.HashSet; + /** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper @@ -45,6 +49,9 @@ public class BaseViewHolder extends RecyclerView.ViewHolder { */ private final SparseArray views; + private final HashSet childClickViewIds; + private final HashSet itemChildLongClickViewIds; + public View convertView; @@ -57,10 +64,20 @@ public class BaseViewHolder extends RecyclerView.ViewHolder { protected BaseViewHolder(View view) { super(view); this.views = new SparseArray(); + this.childClickViewIds = new HashSet<>(); + this.itemChildLongClickViewIds = new HashSet<>(); convertView = view; } + public HashSet getItemChildLongClickViewIds() { + return itemChildLongClickViewIds; + } + + public HashSet getChildClickViewIds() { + return childClickViewIds; + } + public View getConvertView() { return convertView; @@ -79,6 +96,12 @@ public BaseViewHolder setText(int viewId, CharSequence value) { return this; } + public BaseViewHolder setText(int viewId, @StringRes int strId) { + TextView view = getView(viewId); + view.setText(strId); + return this; + } + /** * Will set the image of an ImageView from a resource id. * @@ -86,7 +109,7 @@ public BaseViewHolder setText(int viewId, CharSequence value) { * @param imageResId The image resource id. * @return The BaseViewHolder for chaining. */ - public BaseViewHolder setImageResource(int viewId, int imageResId) { + public BaseViewHolder setImageResource(int viewId,@DrawableRes int imageResId) { ImageView view = getView(viewId); view.setImageResource(imageResId); return this; @@ -112,7 +135,7 @@ public BaseViewHolder setBackgroundColor(int viewId, int color) { * @param backgroundRes A resource to use as a background. * @return The BaseViewHolder for chaining. */ - public BaseViewHolder setBackgroundRes(int viewId, int backgroundRes) { + public BaseViewHolder setBackgroundRes(int viewId, @DrawableRes int backgroundRes) { View view = getView(viewId); view.setBackgroundResource(backgroundRes); return this; @@ -289,37 +312,38 @@ public BaseViewHolder setRating(int viewId, float rating, int max) { /** * Sets the on click listener of the view. - * * @param viewId The view id. * @param listener The on click listener; * @return The BaseViewHolder for chaining. */ + @Deprecated public BaseViewHolder setOnClickListener(int viewId, View.OnClickListener listener) { View view = getView(viewId); view.setOnClickListener(listener); return this; } - public BaseViewHolder setOnClickListener(int viewId, BaseQuickAdapter.OnItemChildClickListener listener) { - View view = getView(viewId); - listener.mViewHolder = this; - view.setOnClickListener(listener); + /** + * add childView id + * @param viewId add the child view id can support childview click + * @return + */ + public BaseViewHolder addOnClickListener(int viewId) { + childClickViewIds.add(viewId); return this; } /** - * Sets the on longClick listener of the view. + * add long click view id * @param viewId - * @param listener * @return */ - public BaseViewHolder setOnLongClickListener(int viewId, BaseQuickAdapter.OnItemChildLongClickListener listener) { - View view = getView(viewId); - listener.mViewHolder = this; - view.setOnLongClickListener(listener); + public BaseViewHolder addOnLongClickListener(int viewId){ + itemChildLongClickViewIds.add(viewId); return this; } + /** * Sets the on touch listener of the view. * diff --git a/library/src/main/java/com/chad/library/adapter/base/entity/AbstractExpandableItem.java b/library/src/main/java/com/chad/library/adapter/base/entity/AbstractExpandableItem.java new file mode 100644 index 000000000..866fe6ff8 --- /dev/null +++ b/library/src/main/java/com/chad/library/adapter/base/entity/AbstractExpandableItem.java @@ -0,0 +1,80 @@ +package com.chad.library.adapter.base.entity; + +import java.util.ArrayList; +import java.util.List; + +/** + *

A helper to implement expandable item.

+ *

if you don't want to extent a class, you can also implement the interface IExpandable

+ * Created by luoxw on 2016/8/9. + */ +public abstract class AbstractExpandableItem implements IExpandable { + protected boolean mExpandable = false; + protected List mSubItems; + + @Override + public boolean isExpanded() { + return mExpandable; + } + + @Override + public void setExpanded(boolean expanded) { + mExpandable = expanded; + } + + @Override + public List getSubItems() { + return mSubItems; + } + + public boolean hasSubItem() { + return mSubItems != null && mSubItems.size() > 0; + } + + public void setSubItems(List list) { + mSubItems = list; + } + + public T getSubItem(int position) { + if (hasSubItem() && position < mSubItems.size()) { + return mSubItems.get(position); + } else { + return null; + } + } + + public int getSubItemPosition(T subItem) { + return mSubItems != null ? mSubItems.indexOf(subItem) : -1; + } + + public void addSubItem(T subItem) { + if (mSubItems == null) { + mSubItems = new ArrayList<>(); + } + mSubItems.add(subItem); + } + + public void addSubItem(int position, T subItem) { + if (mSubItems != null && position >= 0 && position < mSubItems.size()) { + mSubItems.add(position, subItem); + } else { + addSubItem(subItem); + } + } + + public boolean contains(T subItem) { + return mSubItems != null && mSubItems.contains(subItem); + } + + public boolean removeSubItem(T subItem) { + return mSubItems != null && mSubItems.remove(subItem); + } + + public boolean removeSubItem(int position) { + if (mSubItems != null && position >= 0 && position < mSubItems.size()) { + mSubItems.remove(position); + return true; + } + return false; + } +} diff --git a/library/src/main/java/com/chad/library/adapter/base/entity/IExpandable.java b/library/src/main/java/com/chad/library/adapter/base/entity/IExpandable.java new file mode 100644 index 000000000..d6efc255b --- /dev/null +++ b/library/src/main/java/com/chad/library/adapter/base/entity/IExpandable.java @@ -0,0 +1,13 @@ +package com.chad.library.adapter.base.entity; + +import java.util.List; + +/** + * implement the interface if the item is expandable + * Created by luoxw on 2016/8/8. + */ +public interface IExpandable { + boolean isExpanded(); + void setExpanded(boolean expanded); + List getSubItems(); +} diff --git a/library/src/main/java/com/chad/library/adapter/base/entity/MultiItemEntity.java b/library/src/main/java/com/chad/library/adapter/base/entity/MultiItemEntity.java index abafdd0ea..12a7713d8 100644 --- a/library/src/main/java/com/chad/library/adapter/base/entity/MultiItemEntity.java +++ b/library/src/main/java/com/chad/library/adapter/base/entity/MultiItemEntity.java @@ -1,18 +1,10 @@ package com.chad.library.adapter.base.entity; -import java.io.Serializable; - /** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper */ -public abstract class MultiItemEntity implements Serializable{ - protected int itemType; +public interface MultiItemEntity { - public int getItemType() { - return itemType; - } + int getItemType(); - public void setItemType(int itemType) { - this.itemType = itemType; - } } diff --git a/library/src/main/java/com/chad/library/adapter/base/listener/OnItemChildClickListener.java b/library/src/main/java/com/chad/library/adapter/base/listener/OnItemChildClickListener.java new file mode 100644 index 000000000..382d1d1bd --- /dev/null +++ b/library/src/main/java/com/chad/library/adapter/base/listener/OnItemChildClickListener.java @@ -0,0 +1,38 @@ +package com.chad.library.adapter.base.listener; + +import android.view.View; + +import com.chad.library.adapter.base.BaseQuickAdapter; + +/** + * Created by AllenCoder on 2016/8/03. + * A convenience class to extend when you only want to OnItemChildClickListener for a subset + * of all the SimpleClickListener. This implements all methods in the + * {@link SimpleClickListener} + **/ + +public abstract class OnItemChildClickListener extends SimpleClickListener { + + @Override + public void onItemClick(BaseQuickAdapter adapter, View view, int position) { + + } + + @Override + public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) { + + } + + @Override + public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { + SimpleOnItemChildClick(adapter, view, position); + } + + @Override + public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + + } + + public abstract void SimpleOnItemChildClick(BaseQuickAdapter adapter, View view, int position); + +} diff --git a/library/src/main/java/com/chad/library/adapter/base/listener/OnItemChildLongClickListener.java b/library/src/main/java/com/chad/library/adapter/base/listener/OnItemChildLongClickListener.java new file mode 100644 index 000000000..088cf07f1 --- /dev/null +++ b/library/src/main/java/com/chad/library/adapter/base/listener/OnItemChildLongClickListener.java @@ -0,0 +1,36 @@ +package com.chad.library.adapter.base.listener; + +import android.view.View; + +import com.chad.library.adapter.base.BaseQuickAdapter; + +/** + * Created by AllenCoder on 2016/8/03. + * A convenience class to extend when you only want to OnItemChildLongClickListener for a subset + * of all the SimpleClickListener. This implements all methods in the + * {@link SimpleClickListener} + **/ +public abstract class OnItemChildLongClickListener extends SimpleClickListener { + + + @Override + public void onItemClick(BaseQuickAdapter adapter, View view, int position) { + + } + + @Override + public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) { + + } + + @Override + public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { + + } + + @Override + public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + SimpleOnItemChildLongClick(adapter,view,position); + } + public abstract void SimpleOnItemChildLongClick(BaseQuickAdapter adapter, View view, int position); +} diff --git a/library/src/main/java/com/chad/library/adapter/base/listener/OnItemClickListener.java b/library/src/main/java/com/chad/library/adapter/base/listener/OnItemClickListener.java new file mode 100644 index 000000000..a56c9a219 --- /dev/null +++ b/library/src/main/java/com/chad/library/adapter/base/listener/OnItemClickListener.java @@ -0,0 +1,38 @@ +package com.chad.library.adapter.base.listener; + +import android.view.View; + +import com.chad.library.adapter.base.BaseQuickAdapter; + +/** + * Created by AllenCoder on 2016/8/03. + * + * + * A convenience class to extend when you only want to OnItemClickListener for a subset + * of all the SimpleClickListener. This implements all methods in the + * {@link SimpleClickListener} + */ +public abstract class OnItemClickListener extends SimpleClickListener { + + + @Override + public void onItemClick(BaseQuickAdapter adapter, View view, int position) { + SimpleOnItemClick(adapter,view,position); + } + + @Override + public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) { + + } + + @Override + public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { + + } + + @Override + public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + + } + public abstract void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position); +} diff --git a/library/src/main/java/com/chad/library/adapter/base/listener/OnItemLongClickListener.java b/library/src/main/java/com/chad/library/adapter/base/listener/OnItemLongClickListener.java new file mode 100644 index 000000000..9f0e818d6 --- /dev/null +++ b/library/src/main/java/com/chad/library/adapter/base/listener/OnItemLongClickListener.java @@ -0,0 +1,35 @@ +package com.chad.library.adapter.base.listener; + +import android.view.View; + +import com.chad.library.adapter.base.BaseQuickAdapter; + +/** + * create by: allen on 16/8/3. + */ + +public abstract class OnItemLongClickListener extends SimpleClickListener { + + + + + @Override + public void onItemClick(BaseQuickAdapter adapter, View view, int position) { + + } + + @Override + public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) { + SimpleOnItemLongClick( adapter, view, position); + } + + @Override + public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { + + } + + @Override + public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { + } + public abstract void SimpleOnItemLongClick(BaseQuickAdapter adapter, View view, int position); +} diff --git a/library/src/main/java/com/chad/library/adapter/base/listener/SimpleClickListener.java b/library/src/main/java/com/chad/library/adapter/base/listener/SimpleClickListener.java new file mode 100644 index 000000000..561cdd7ad --- /dev/null +++ b/library/src/main/java/com/chad/library/adapter/base/listener/SimpleClickListener.java @@ -0,0 +1,173 @@ +package com.chad.library.adapter.base.listener; + +import android.support.v4.view.GestureDetectorCompat; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.View; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; + +import java.util.Iterator; +import java.util.Set; + +import static com.chad.library.adapter.base.BaseQuickAdapter.EMPTY_VIEW; +import static com.chad.library.adapter.base.BaseQuickAdapter.FOOTER_VIEW; +import static com.chad.library.adapter.base.BaseQuickAdapter.HEADER_VIEW; +import static com.chad.library.adapter.base.BaseQuickAdapter.LOADING_VIEW; + +/** + * Created by AllenCoder on 2016/8/03. + *

+ * This can be useful for applications that wish to implement various forms of click and longclick and childView click + * manipulation of item views within the RecyclerView. SimpleClickListener may intercept + * a touch interaction already in progress even if the SimpleClickListener is already handling that + * gesture stream itself for the purposes of scrolling. + * + * @see RecyclerView.OnItemTouchListener + */ +public abstract class SimpleClickListener implements RecyclerView.OnItemTouchListener { + private GestureDetectorCompat mGestureDetector; + private RecyclerView recyclerView; + private Set childClickViewIds; + private Set longClickViewIds; + protected BaseQuickAdapter baseQuickAdapter; + public static String TAG = "SimpleClickListener"; + + + @Override + public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { + if (recyclerView == null) { + this.recyclerView = rv; + this.baseQuickAdapter = (BaseQuickAdapter) recyclerView.getAdapter(); + mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelperGestureListener(recyclerView)); + } + mGestureDetector.onTouchEvent(e); + return false; + } + + @Override + public void onTouchEvent(RecyclerView rv, MotionEvent e) { + Log.e(TAG, "onTouchEvent: "); + mGestureDetector.onTouchEvent(e); + } + + @Override + public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { + } + + private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener { + private RecyclerView recyclerView; + + public ItemTouchHelperGestureListener(RecyclerView recyclerView) { + this.recyclerView = recyclerView; + } + + @Override + public boolean onSingleTapUp(MotionEvent e) { + View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); + + if (child != null) { + BaseViewHolder vh = (BaseViewHolder) recyclerView.getChildViewHolder(child); + + if (isHeaderOrFooterPosition(vh.getLayoutPosition())) { + return false; + } + childClickViewIds = vh.getChildClickViewIds(); + + if (childClickViewIds != null && childClickViewIds.size() > 0) { + for (Iterator it = childClickViewIds.iterator(); it.hasNext(); ) { + View childView = child.findViewById((Integer) it.next()); + if (inRangeOfView(childView, e)) { + onItemChildClick(baseQuickAdapter, childView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount()); + return true; + } + } + + + onItemClick(baseQuickAdapter, child, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount()); + } else { + onItemClick(baseQuickAdapter, child, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount()); + } + + + } + return true; + } + + @Override + public void onLongPress(MotionEvent e) { + View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); + if (child != null) { + BaseViewHolder vh = (BaseViewHolder) recyclerView.getChildViewHolder(child); + if (!isHeaderOrFooterPosition(vh.getLayoutPosition())) { + longClickViewIds = vh.getItemChildLongClickViewIds(); + if (longClickViewIds != null && longClickViewIds.size() > 0) { + for (Iterator it = longClickViewIds.iterator(); it.hasNext(); ) { + View childView = child.findViewById((Integer) it.next()); + if (inRangeOfView(childView, e)) { + onItemChildLongClick(baseQuickAdapter, childView, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount()); + return; + } + } + } + onItemLongClick(baseQuickAdapter, child, vh.getLayoutPosition() - baseQuickAdapter.getHeaderLayoutCount()); + } + + } + } + + + } + + /** + * Callback method to be invoked when an item in this AdapterView has + * been clicked. + * + * @param view The view within the AdapterView that was clicked (this + * will be a view provided by the adapter) + * @param position The position of the view in the adapter. + */ + public abstract void onItemClick(BaseQuickAdapter adapter, View view, int position); + + /** + * callback method to be invoked when an item in this view has been + * click and held + * + * @param view The view whihin the AbsListView that was clicked + * @param position The position of the view int the adapter + * @return true if the callback consumed the long click ,false otherwise + */ + public abstract void onItemLongClick(BaseQuickAdapter adapter, View view, int position); + + public abstract void onItemChildClick(BaseQuickAdapter adapter, View view, int position); + + public abstract void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position); + + public boolean inRangeOfView(View view, MotionEvent ev) { + int[] location = new int[2]; + view.getLocationOnScreen(location); + int x = location[0]; + int y = location[1]; + if (ev.getRawX() < x + || ev.getRawX() > (x + view.getWidth()) + || ev.getRawY() < y + || ev.getRawY() > (y + view.getHeight())) { + return false; + } + return true; + } + + private boolean isHeaderOrFooterPosition(int position) { + /** + * have a headview and EMPTY_VIEW FOOTER_VIEW LOADING_VIEW + */ + int type = baseQuickAdapter.getItemViewType(position); + return (type == EMPTY_VIEW || type == HEADER_VIEW || type == FOOTER_VIEW || type == LOADING_VIEW); + } + +} + + diff --git a/library/src/main/res/layout/def_load_more_failed.xml b/library/src/main/res/layout/def_load_more_failed.xml new file mode 100644 index 000000000..af0d20f8a --- /dev/null +++ b/library/src/main/res/layout/def_load_more_failed.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/library/src/main/res/values-en/strings.xml b/library/src/main/res/values-en/strings.xml index 0199de443..caade3214 100644 --- a/library/src/main/res/values-en/strings.xml +++ b/library/src/main/res/values-en/strings.xml @@ -1,3 +1,4 @@ Loading... + load more failed diff --git a/library/src/main/res/values/strings.xml b/library/src/main/res/values/strings.xml index 79345ebea..6f14eebaf 100644 --- a/library/src/main/res/values/strings.xml +++ b/library/src/main/res/values/strings.xml @@ -1,4 +1,5 @@ Library 正在加载中... + 加载失败,请点我重试