Skip to content

Commit

Permalink
稳定版
Browse files Browse the repository at this point in the history
  • Loading branch information
weimingjue committed Aug 15, 2020
1 parent 7dffb70 commit 9f9fbcf
Show file tree
Hide file tree
Showing 40 changed files with 3,383 additions and 8 deletions.
17 changes: 9 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
*.iml
.gradle
/local.properties
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
*.apk
*.zip
local.properties
*.hprof
/captures
.externalNativeBuild
~$*
.DS_Store
.idea
.gradle
build
137 changes: 137 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# 代码非常简单,基于dataBinding

## 详细示例见本项目app下的MainActivity
### 说明:adapter的功能、方向及逻辑已经明确,后续将稳定发版,不会有较大改动

一个listAdapter只需要如下一行(没错,总共就一行)
```
BaseAdapterRvList<?, String> adapter = BaseAdapterRvList.createAdapter(R.layout.adapter_main_list);
```
当然,你的xml是基于dataBinding的
```
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<!-- adapter默认会设置并刷新“bean”这个属性-->
<variable
name="bean"
type="String" />
</data>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:padding="10dp"
android:text="@{bean}"
android:textColor="#333"
android:textSize="20sp"
tools:text="这是文本" />
</layout>
```
自带点击事件
```
adapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(@NonNull View view, int listPosition) {
}
@Override
public boolean onItemLongClick(@NonNull View view, int listPosition) {
return true;
}
@Override
protected void onFooterClick(@NonNull View view) {
super.onFooterClick(view);
}
//...header、footer long click
});
```
自带header、footer
```
adapter.setHeaderView(view);
adapter.setFooterView(view);
```
当然你也可以自定义一些简单逻辑
```
BaseAdapterRvList<AdapterMainListBinding, String> adapter = BaseAdapterRvList.createAdapter(list, R.layout.adapter_main_list,
(holder, listPosition, s) -> {
if (s.contains("10")) {
holder.itemView.setBackgroundColor(0xff999999);
}
});//回调还有onViewHolderCreated方法
```
也可以完全自定义(没有看错,不需要layoutId)
```
public static class ListAdapter extends BaseAdapterRvList<AdapterMainListBinding, String> {
@Override
public void onBindListViewHolder(@NonNull BaseViewHolder<AdapterMainListBinding> 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);
} else {
holder.getBinding().viewBackground.setBackgroundColor(0xffffffff);
}
}
@NonNull
@Override
public BaseViewHolder<AdapterMainListBinding> onCreateListViewHolder(@NonNull ViewGroup parent) {
BaseViewHolder<AdapterMainListBinding> holder = super.onCreateListViewHolder(parent);
holder.itemView.setBackgroundColor(0xffeeeeee);
return holder;
}
}
```
ViewPager的Fragment更简单
```
mVp.setAdapter(new BaseFragmentPagerAdapter(getSupportFragmentManager(), mFrags));
//或
mVp.setAdapter(new BaseFragmentPagerAdapter(getSupportFragmentManager(), frag1,frag2...));
//动态修改frag
mAdapter = new BaseFragmentStatePagerAdapter(getSupportFragmentManager(), mFrags);
mVp.setAdapter(mAdapter);
...
mAdapter.getFragments().add(xxx);//由于内部有新的list,所以并不能用自己的mFrags
mAdapter.getFragments().remove(yyy);
mAdapter.notifyDataSetChanged();
//解决动态修改刷新白屏的问题
BaseFragmentNotifyAdapter adapter = new BaseFragmentNotifyAdapter(getSupportFragmentManager(), mFrags);
mVp.setAdapter(adapter);
...
adapter.notifyAllItem(1);//保留展示的frag这样就不会白屏了,想要刷新这个frag当然需要自己frag内部刷新了,详见app下的示例
```
还有适用于各种复杂样式的adapter容器(如:聊天列表,首页、今日头条的列表等):
```
本项目已默认导入,直接使用即可:https://github.com/weimingjue/BaseContainerAdapter
```

## 导入方式
你的build.gradle要有jitpack.io,大致如下
```
allprojects {
repositories {
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://jitpack.io' }
google()
jcenter()
}
}
```

### AndroidX dataBinding:
`(api或)implementation 'com.github.weimingjue:BaseAdapter:3.61'`

不需要layoutId的混淆要求:
```
#框架特殊要求
# 根据泛型获取res资源需要
-keep class * extends androidx.databinding.ViewDataBinding
```
34 changes: 34 additions & 0 deletions adapters/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apply plugin: 'com.android.library'

android {
compileSdkVersion COMPILE_SDK_VERSION

defaultConfig {
minSdkVersion MIN_SDK_VERSION
targetSdkVersion TARGET_SDK_VERSION
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

dataBinding {
enabled = true
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
//张鸿洋的flowLayout
implementation 'com.zhy:flowlayout-lib:1.0.3'

//自己的适用于超复杂列表样式,如:聊天、首页等
api 'com.github.weimingjue:BaseContainerAdapter:3.0.1'
}
1 change: 1 addition & 0 deletions adapters/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<manifest package="com.wang.adapters" />
201 changes: 201 additions & 0 deletions adapters/src/main/java/com/wang/adapters/adapter/BaseAdapterLvs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
package com.wang.adapters.adapter;

import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;

import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.viewpager.widget.PagerAdapter;

import com.wang.adapters.R;
import com.wang.adapters.interfaces.OnItemClickListener;
import com.wang.container.holder.BaseViewHolder;
import com.wang.container.interfaces.IAdapter;
import com.wang.container.interfaces.IListAdapter;

/**
* 基类adapter,适用于listView、gridView、viewPager
* rv已单独写{@link BaseAdapterRv}
*/
public abstract class BaseAdapterLvs extends PagerAdapter implements ListAdapter, SpinnerAdapter, IAdapter<OnItemClickListener> {

public final String TAG = getClass().getSimpleName();
private final ViewRecycler<View> mRecycler = new ViewRecycler<>();
protected OnItemClickListener mListener;

///////////////////////////////////////////////////////////////////////////
// lv相关
///////////////////////////////////////////////////////////////////////////
public final long getItemId(int position) {
return position;
}

@Override
public final View getView(int position, View convertView, ViewGroup parent) {
BaseViewHolder holder;
if (convertView == null || convertView.getTag(R.id.tag_view_holder) == null) {
//模仿recyclerview,除了bind是position外,其他都是viewType
holder = createViewHolder(parent, getItemViewType(position));
} else {
holder = (BaseViewHolder) convertView.getTag(R.id.tag_view_holder);
}
bindViewHolder(holder, position);
return holder.itemView;
}

@Override
public final boolean areAllItemsEnabled() {
return true;
}

@Override
public final boolean isEnabled(int position) {
return true;
}

@Override
public final View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position, convertView, parent);
}

/**
* 此处是lv用到,list的空判断见{@link IListAdapter#isEmptyList}
*/
@RequiresApi(999)
@Override
public final boolean isEmpty() {
return getItemCount() == 0;
}

@Override
public boolean hasStableIds() {
return false;
}

/**
* lv为了方便,可以在lv直接获取你想要的数据,但是理论上没啥用
* list的使用见{@link IListAdapter}的get、clear、addAll
*/
@Override
public final Object getItem(int position) {
return null;
}

///////////////////////////////////////////////////////////////////////////
// vp相关
///////////////////////////////////////////////////////////////////////////
@NonNull
@Override
public final Object instantiateItem(@NonNull ViewGroup container, int position) {
//取缓存
View convertView = mRecycler.get(getItemViewType(position));
//和lv一样,直接复用代码
View view = getView(position, convertView, container);
container.addView(view);
return view;
}

@Override
public final void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
mRecycler.recycleItem(container, (View) object, getItemViewType(position));
}

@Override
public final boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}

/**
* POSITION_UNCHANGED:永远都在原来的position(notify时不会{@link #destroyItem},也不会{@link #instantiateItem})
* POSITION_NONE:没有位置(notify时会重新调两个方法来添加新视图)
*/
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}

/**
* 不可继承,请使用{@link #getItemCount}
*/
@Override
public final int getCount() {
return getItemCount();
}

@NonNull
public final BaseViewHolder createViewHolder(@NonNull ViewGroup parent, int viewType) {
return onCreateViewHolder(parent, viewType);
}

public final void bindViewHolder(BaseViewHolder holder, int position) {
onBindViewHolder(holder, position);
}

@NonNull
public final BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
BaseViewHolder holder = onCreateViewHolder2(parent, viewType);
holder.itemView.setTag(R.id.tag_view_holder, holder);
holder.itemView.setTag(R.id.tag_view_adapter, this);
return holder;
}

public final void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
//设置点击事件,不判断会顶掉lv的itemClick事件
if (mListener != null) {
holder.itemView.setOnClickListener(mListener);
holder.itemView.setOnLongClickListener(mListener);
}
holder.setLvPosition(position);//设置position
onBindViewHolder2(holder, position);
}

///////////////////////////////////////////////////////////////////////////
// 以下是可能用到的父类方法
///////////////////////////////////////////////////////////////////////////

/**
* lv用到,getItemViewType的个数
* <p>
* 巨坑,没啥用:
* 1.必须大于0大于getItemViewType的最大值,并且不能太大,见{@link android.widget.AbsListView}的RecycleBin)
* 2.多条目必须重写
*/
@IntRange(from = 1, to = 50)
@Override
public int getViewTypeCount() {
return 1;
}

/**
* lv多条目也必须重写{@link #getViewTypeCount()}
* <p>
* 必须大于0,原因同上
*/
@IntRange(from = 0)
@Override
public int getItemViewType(int position) {
return 0;
}

///////////////////////////////////////////////////////////////////////////
// 以下是增加的方法
///////////////////////////////////////////////////////////////////////////

protected abstract void onBindViewHolder2(@NonNull BaseViewHolder holder, int position);

@NonNull
protected abstract BaseViewHolder onCreateViewHolder2(@NonNull ViewGroup parent, int viewType);

/**
* 这里的点击事件不会因有checkbox而被抢焦点
* 里面回调里也有{@link OnItemClickListener#onItemLongClick}、header、footer点击长按
*/
public void setOnItemClickListener(@Nullable OnItemClickListener listener) {
mListener = listener;
notifyDataSetChanged();
}
}
Loading

0 comments on commit 9f9fbcf

Please sign in to comment.