diff --git a/README.md b/README.md index 9b7c108..e04f6bb 100644 --- a/README.md +++ b/README.md @@ -84,12 +84,61 @@ BaseAdapterRvList adapter = BaseAdapterRvList.cr @NonNull @Override public BaseViewHolder onCreateListViewHolder(@NonNull ViewGroup parent) { - BaseViewHolder holder = super.onCreateListViewHolder(parent); + BaseViewHolder holder = super.onCreateListViewHolder(parent);//也可以不用super holder.itemView.setBackgroundColor(0xffeeeeee); return holder; } } ``` +adapter里有个button,点完后还要写个回调给Activity???反正我是不喜欢: +``` + public void onBindListViewHolder(@NonNull BaseViewHolder holder, int listPosition, TestBean bean) { + setItemViewClick(holder.getBinding().btButton, holder); + } + ... + adapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull View view, int listPosition) { + switch (view.getId()) { + case R.id.bt_button: + toast("没想到吧,还能这样玩:" + listPosition); + break; + default: + toast("你点击了整个条目:" + listPosition); + break; + } + } + }); +``` +adapter里又套了一个RecyclerView,简直是回调地狱啊...完全受不了: +``` + public void onBindListViewHolder(@NonNull BaseViewHolder holder, int listPosition, TestBean bean) { + //需提前setAdapter(在bind或者每次create时) + setItemRvData(holder.getBinding().rvItemList, holder, bean.itemTextList); + ... + adapter.setOnItemClickListener(new OnItemItemClickListener() { + @Override + public void onParentItemClick(@NonNull View view, int parentPosition) { + toast("你点击了外层:" + parentPosition); + } + + @Override + public void onChildItemClick(@NonNull View view, int parentPosition, int childPosition) { + toast("你点击了外层:" + parentPosition + ",内层:" + childPosition); + } + + @Override + public void onParentHeaderClick(@NonNull View view) { + toast("你点击了外层:header"); + } + + @Override + public void onChildHeaderClick(@NonNull View view, int parentPosition) { + toast("你点击了外层:" + parentPosition + ",内层:header"); + } + //...footer、longClick等都有,需要多看看 + }); +``` ViewPager的Fragment更简单 ``` mVp.setAdapter(new BaseFragmentPagerAdapter(getSupportFragmentManager(), mFrags)); @@ -131,7 +180,7 @@ allprojects { 不需要layoutId的混淆要求: ``` -#框架特殊要求 +# 框架特殊要求 # 根据泛型获取res资源需要 -keep class * extends androidx.databinding.ViewDataBinding ``` \ No newline at end of file diff --git a/adapters/build.gradle b/adapters/build.gradle index 9cc76ba..ac6132f 100644 --- a/adapters/build.gradle +++ b/adapters/build.gradle @@ -30,5 +30,5 @@ dependencies { implementation 'com.zhy:flowlayout-lib:1.0.3' //自己的适用于超复杂列表样式,如:聊天、首页等 - api 'com.github.weimingjue:BaseContainerAdapter:3.0.2' + api 'com.github.weimingjue:BaseContainerAdapter:3.0.3' } diff --git a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterLvs.java b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterLvs.java index f48ac95..25d6a1e 100644 --- a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterLvs.java +++ b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterLvs.java @@ -144,11 +144,12 @@ public final BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int vi } public final void onBindViewHolder(@NonNull BaseViewHolder holder, int position) { - //设置点击事件,不判断会顶掉lv的itemClick事件 - if (mListener != null) { - holder.itemView.setOnClickListener(mListener); - holder.itemView.setOnLongClickListener(mListener); - } + //设置点击事件 + holder.itemView.setOnClickListener(mListener); + holder.itemView.setOnLongClickListener(mListener); + //防止null时抢占事件 + holder.itemView.setClickable(mListener != null); + holder.itemView.setLongClickable(mListener != null); holder.setLvPosition(position);//设置position onBindViewHolder2(holder, position); } diff --git a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterLvsListCycle.java b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterLvsListCycle.java index 55cc6c4..6020500 100644 --- a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterLvsListCycle.java +++ b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterLvsListCycle.java @@ -10,6 +10,7 @@ import com.wang.adapters.helper.ListAdapterHelper; import com.wang.adapters.interfaces.OnItemClickListener; +import com.wang.adapters.utils.ArrayUtils; import com.wang.container.holder.BaseViewHolder; import com.wang.container.interfaces.IListAdapter; @@ -23,6 +24,8 @@ public abstract class BaseAdapterLvsListCycle private final ListAdapterHelper mHelper; + private boolean mIsCycle = true; + /** * 资源id已经不是必须的了 *

@@ -45,7 +48,10 @@ public BaseAdapterLvsListCycle(@LayoutRes int layoutId, @Nullable List lis @Override public final int getItemCount() { - return getList().isEmpty() ? 0 : Integer.MAX_VALUE; + if (ArrayUtils.isEmpty(getList())) { + return 0; + } + return isCycle() ? Integer.MAX_VALUE : size(); } @Override @@ -123,4 +129,18 @@ public BEAN get(int position) { public BaseViewHolder onCreateListViewHolder(@NonNull ViewGroup parent) { return mHelper.onCreateDefaultViewHolder(parent, BaseAdapterLvsListCycle.class, getClass()); } + + /** + * @param isCycle true 默认值,可循环滑动 + */ + public void setCycle(boolean isCycle) { + if (isCycle != mIsCycle) { + mIsCycle = isCycle; + notifyDataSetChanged(); + } + } + + public boolean isCycle() { + return mIsCycle; + } } diff --git a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRv.java b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRv.java index 75d7d16..097f109 100644 --- a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRv.java +++ b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRv.java @@ -5,7 +5,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.databinding.ViewDataBinding; import androidx.recyclerview.widget.RecyclerView; import com.wang.adapters.R; @@ -37,9 +36,12 @@ public final BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int vi @Override public final void onBindViewHolder(@NonNull BaseViewHolder holder, int position) { - //创建点击事件 + //设置点击事件 holder.itemView.setOnClickListener(mListener); holder.itemView.setOnLongClickListener(mListener); + //防止null时抢占事件 + holder.itemView.setClickable(mListener != null); + holder.itemView.setLongClickable(mListener != null); onBindViewHolder2(holder, position); } diff --git a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRvList.java b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRvList.java index 7afef8b..f7a06b7 100644 --- a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRvList.java +++ b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRvList.java @@ -99,7 +99,7 @@ public BaseViewHolder onCreateListViewHolder(@NonNull ViewGroup parent) { } /** - * @param view null表示删除 + * @param view null表示删除,view的parent为FrameLayout,默认match、wrap */ public void setHeaderView(@Nullable View view) { mHelper.setHeaderView(view); @@ -112,7 +112,7 @@ public View getHeaderView() { } /** - * @param view null表示删除 + * @param view null表示删除,view的parent为FrameLayout,默认match、wrap */ @Override public void setFooterView(@Nullable View view) { @@ -130,17 +130,26 @@ public View getFooterView() { //////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** - * 懒得不能再懒了的写法 - * 就资源id,数据在xml里修改 - * - * @param layoutId create时的资源id + * 就资源id,使用dataBinding绑定数据 */ public static BaseAdapterRvList createAdapter(@LayoutRes final int layoutId) { - return createAdapter(null, layoutId, null); + return createAdapter(null, layoutId); + } + + /** + * 就资源id,使用dataBinding绑定数据 + */ + public static BaseAdapterRvList createAdapter(@Nullable List list, @LayoutRes final int layoutId) { + return createAdapter(list, layoutId, null); } + /** + * 资源id+回调 + * + * @param layoutId 资源id,必须有 + */ public static BaseAdapterRvList createAdapter - (@Nullable List list, @LayoutRes final int layoutId, @Nullable final OnAdapterBindListener listener) { + (@Nullable List list, @LayoutRes final int layoutId, @Nullable final OnAdapterBindListener listener) { return new BaseAdapterRvList(layoutId, list) { @NonNull diff --git a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRvListCycle.java b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRvListCycle.java index 1cd1160..cbb1e41 100644 --- a/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRvListCycle.java +++ b/adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterRvListCycle.java @@ -10,6 +10,7 @@ import com.wang.adapters.helper.ListAdapterHelper; import com.wang.adapters.interfaces.OnItemClickListener; +import com.wang.adapters.utils.ArrayUtils; import com.wang.container.holder.BaseViewHolder; import com.wang.container.interfaces.IListAdapter; @@ -23,6 +24,8 @@ public abstract class BaseAdapterRvListCycle e private final ListAdapterHelper mHelper; + private boolean mIsCycle = true; + /** * 资源id已经不是必须的了 *

@@ -45,7 +48,10 @@ public BaseAdapterRvListCycle(@LayoutRes int layoutId, @Nullable List list @Override public final int getItemCount() { - return getList().isEmpty() ? 0 : Integer.MAX_VALUE; + if (ArrayUtils.isEmpty(getList())) { + return 0; + } + return isCycle() ? Integer.MAX_VALUE : size(); } @Override @@ -123,4 +129,18 @@ public BEAN get(int position) { public BaseViewHolder onCreateListViewHolder(@NonNull ViewGroup parent) { return mHelper.onCreateDefaultViewHolder(parent, BaseAdapterLvsListCycle.class, getClass()); } + + /** + * @param isCycle true 默认值,可循环滑动 + */ + public void setCycle(boolean isCycle) { + if (isCycle != mIsCycle) { + mIsCycle = isCycle; + notifyDataSetChanged(); + } + } + + public boolean isCycle() { + return mIsCycle; + } } diff --git a/adapters/src/main/java/com/wang/adapters/interfaces/OnItemClickListener.java b/adapters/src/main/java/com/wang/adapters/interfaces/OnItemClickListener.java index b90f118..78bee39 100644 --- a/adapters/src/main/java/com/wang/adapters/interfaces/OnItemClickListener.java +++ b/adapters/src/main/java/com/wang/adapters/interfaces/OnItemClickListener.java @@ -54,7 +54,7 @@ default boolean onLongClick(@NonNull View view) { /** * 获取当前view所保存的position */ - @Deprecated//不需要重写 + @Deprecated//不需要重写,可以使用 default IAdapter getAdapter(@NonNull View view) { return (IAdapter) view.getTag(R.id.tag_view_adapter); } @@ -62,7 +62,7 @@ default IAdapter getAdapter(@NonNull View view) { /** * 获取当前view所在的ViewHolder */ - @Deprecated//不需要重写 + @Deprecated//不需要重写,可以使用 default BaseViewHolder getViewHolder(@NonNull View view) { return (BaseViewHolder) view.getTag(R.id.tag_view_holder); } @@ -72,7 +72,7 @@ default BaseViewHolder getViewHolder(@NonNull View view) { * * @return {@link #POSITION_HEADER}{@link #POSITION_FOOTER}或者0-list.size */ - @Deprecated//不需要重写 + @Deprecated//不需要重写,可以使用 default int getFormatPosition(IAdapter adapter, int position) { if (adapter instanceof IListAdapter) { //listAdapter有header、footer事件 diff --git a/adapters/src/main/java/com/wang/adapters/interfaces/OnItemItemClickListener.java b/adapters/src/main/java/com/wang/adapters/interfaces/OnItemItemClickListener.java index 5d0bfbd..9d72497 100644 --- a/adapters/src/main/java/com/wang/adapters/interfaces/OnItemItemClickListener.java +++ b/adapters/src/main/java/com/wang/adapters/interfaces/OnItemItemClickListener.java @@ -129,7 +129,7 @@ default boolean performClick(View view, @ClickType int clickType, int listPositi /** * 外层的position需要遍历 */ - @Deprecated//不需要重写 + @Deprecated//不需要重写,可以使用 default IAdapter getParentAdapter(@NonNull View view) { ViewParent parent = view.getParent(); while (parent != null) { @@ -147,7 +147,7 @@ default IAdapter getParentAdapter(@NonNull View view) { /** * 获取当前view所在的ViewHolder */ - @Deprecated//不需要重写 + @Deprecated//不需要重写,可以使用 default BaseViewHolder getParentViewHolder(@NonNull View view) { ViewParent parent = view.getParent(); while (parent != null) { diff --git a/app/src/main/java/com/wang/example/MainActivity.java b/app/src/main/java/com/wang/example/MainActivity.java index 14b5822..7030003 100644 --- a/app/src/main/java/com/wang/example/MainActivity.java +++ b/app/src/main/java/com/wang/example/MainActivity.java @@ -4,21 +4,26 @@ import android.os.Bundle; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.databinding.ViewDataBinding; import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.wang.adapters.adapter.BaseAdapterRvList; -import com.wang.adapters.interfaces.OnItemClickListener; +import com.wang.adapters.interfaces.OnItemItemClickListener; import com.wang.container.holder.BaseViewHolder; import com.wang.example.databinding.AdapterMainListBinding; import java.util.ArrayList; +import java.util.List; public class MainActivity extends AppCompatActivity { @@ -28,12 +33,7 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - findViewById(R.id.tv_main_vp).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startActivity(ViewPagerFragActivity.class); - } - }); + findViewById(R.id.tv_main_vp).setOnClickListener(v -> startActivity(ViewPagerFragActivity.class)); mRv = findViewById(R.id.rv_main); listTest(); } @@ -42,14 +42,21 @@ public void onClick(View v) { * 简单的列表测试 */ private void listTest() { - GridLayoutManager manager = new GridLayoutManager(this, 2); - mRv.setLayoutManager(manager); - final ArrayList list = new ArrayList<>(); - for (int i = 0; i < 200; i++) { - list.add("第" + i); + mRv.setLayoutManager(new LinearLayoutManager(this)); + final ArrayList list = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + TestBean tb = new TestBean(); + tb.text = "第" + i; + if (i % 5 == 0) { + tb.itemTextList = new ArrayList<>(); + for (int j = 0; j < 10; j++) { + tb.itemTextList.add("第" + i + ",子" + j); + } + } + list.add(tb); } // BaseAdapterRvList adapter = BaseAdapterRvList.createAdapter(R.layout.adapter_main_list); - BaseAdapterRvList adapter = new ListAdapter(); + ListAdapter adapter = new ListAdapter(); // BaseAdapterRvList adapter = BaseAdapterRvList.createAdapter(null, R.layout.adapter_main_list, // (holder, listPosition, s) -> { // if (s.contains("10")) { @@ -59,48 +66,61 @@ private void listTest() { adapter.setListAndNotifyDataSetChanged(list); mRv.setAdapter(adapter); //设置点击事件 - adapter.setOnItemClickListener(new OnItemClickListener() { + adapter.setOnItemClickListener(new OnItemItemClickListener() { @Override - public void onItemClick(@NonNull View view, int listPosition) { - Toast.makeText(MainActivity.this, "点击第" + list.get(listPosition), Toast.LENGTH_SHORT).show(); + public void onParentItemClick(@NonNull View view, int parentPosition) { + switch (view.getId()) { + case R.id.bt_button: + toast("没想到吧,还能这样玩"); + break; + default: + toast("你点击了外层:" + parentPosition); + break; + } } @Override - public boolean onItemLongClick(@NonNull View view, int listPosition) { - Toast.makeText(MainActivity.this, "长按第" + list.get(listPosition), Toast.LENGTH_SHORT).show(); - return true; + public void onChildItemClick(@NonNull View view, int parentPosition, int childPosition) { + toast("你点击了外层:" + parentPosition + ",内层:" + childPosition); } @Override - public void onFooterClick(@NonNull View view) { - Toast.makeText(MainActivity.this, "footer被点击", Toast.LENGTH_SHORT).show(); + public void onParentHeaderClick(@NonNull View view) { + toast("你点击了外层:header"); + } + + @Override + public void onChildHeaderClick(@NonNull View view, int parentPosition) { + toast("你点击了外层:" + parentPosition + ",内层:header"); } }); + //添加头 + AppCompatTextView tv = new AppCompatTextView(this); + tv.setText("外层的header"); + tv.setTextSize(30); + adapter.setHeaderView(tv); //添加尾 AppCompatImageView iv = new AppCompatImageView(this); iv.setImageResource(R.mipmap.ic_launcher); iv.setAdjustViewBounds(true); adapter.setFooterView(iv); - //GridLayoutManager需要将头或尾占多行 - manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { - @Override - public int getSpanSize(int position) { - return position == list.size() ? 2 : 1; - } - }); } - public static class ListAdapter extends BaseAdapterRvList { + public static class ListAdapter extends BaseAdapterRvList { @Override - public void onBindListViewHolder(@NonNull BaseViewHolder holder, int listPosition, String s) { - if (s.contains("100")) { - getList().set(listPosition, "改掉了100");//后面会调用刷新dataBinding - holder.getBinding().viewBackground.setBackgroundColor(0xff00ff00); - } else if (s.contains("10")) { - holder.getBinding().viewBackground.setBackgroundColor(0xff999999); + public void onBindListViewHolder(@NonNull BaseViewHolder holder, int listPosition, TestBean bean) { + setItemViewClick(holder.getBinding().btButton, holder); + setItemRvData(holder.getBinding().rvItemList, holder, bean.itemTextList); + MyAdapter adapter = (MyAdapter) holder.getBinding().rvItemList.getAdapter(); + if (bean.itemTextList != null && bean.itemTextList.size() > 0) { + TextView footerTv = new TextView(holder.getContext()); + footerTv.setText("内层的footer,外层position" + listPosition); + footerTv.setTextColor(0xff999999); + footerTv.setTextSize(13); + adapter.setFooterView(footerTv); } else { - holder.getBinding().viewBackground.setBackgroundColor(0xffffffff); + adapter.setFooterView(null); } } @@ -108,12 +128,49 @@ public void onBindListViewHolder(@NonNull BaseViewHolder @Override public BaseViewHolder onCreateListViewHolder(@NonNull ViewGroup parent) { BaseViewHolder holder = super.onCreateListViewHolder(parent); - holder.itemView.setBackgroundColor(0xffeeeeee); + holder.getBinding().rvItemList.setLayoutManager(new GridLayoutManager(parent.getContext(), 2)); + MyAdapter adapter = new MyAdapter(); + TextView headerTv = new TextView(parent.getContext()); + headerTv.setText("内层的header一直有"); + headerTv.setTextColor(0xff999999); + headerTv.setTextSize(13); + adapter.setHeaderView(headerTv); + holder.getBinding().rvItemList.setAdapter(adapter); + holder.getBinding().rvItemList.setNestedScrollingEnabled(false); return holder; } + + private class MyAdapter extends BaseAdapterRvList { + + @Override + public void onBindListViewHolder(@NonNull BaseViewHolder holder, int listPosition, String bean) { + TextView tv = (TextView) holder.itemView; + tv.setText(bean); + } + + @NonNull + @Override + public BaseViewHolder onCreateListViewHolder(@NonNull ViewGroup parent) { + TextView tv = new AppCompatTextView(parent.getContext()); + tv.setTextColor(0xffff00ff); + tv.setTextSize(15); + tv.setPadding(50, 10, 50, 10); + tv.setTag(R.id.tag_view_no_data_binding, ""); + return new BaseViewHolder<>(tv); + } + } + } + + public static class TestBean { + public String text; + public List itemTextList; } public void startActivity(Class c) { startActivity(new Intent(this, c)); } + + public void toast(String st) { + Toast.makeText(this, st, Toast.LENGTH_SHORT).show(); + } } diff --git a/app/src/main/res/layout/adapter_main_list.xml b/app/src/main/res/layout/adapter_main_list.xml index 783928d..2c2aa63 100644 --- a/app/src/main/res/layout/adapter_main_list.xml +++ b/app/src/main/res/layout/adapter_main_list.xml @@ -7,26 +7,33 @@ + type="com.wang.example.MainActivity.TestBean" /> + android:orientation="vertical"> - - +