//首先在progect下加依赖
buildscript {
repositories {
google()
jcenter()
mavenCentral() // add repository
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
//再在module下加依赖
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'//万能RecyclerView适配器
implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.5.1'
implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.5.1'//没有使用特殊Header,可以不加这行
mRefreshLayout.setOnRefreshListener(new OnRefreshListener(){
@Override
public void onRefresh(RefreshLayout refreshlayout){
requestData();
}
});
mRefreshLayout.setOnLoadmoreListener(new OnLoadmoreListener(){
@Override
public void onLoadmore(RefreshLayout refreshlayout){
mRefreshLayout.finishLoadmore(2000);
}
});
名称-name | 格式-format | 描述-description |
---|---|---|
srlPrimaryColor | color | 主题颜色 |
srlAccentColor | color | 强调颜色 |
srlReboundDuration | integer | 释放后回弹动画时长 |
srlHeaderHeight | dimension | Header的标准高度 |
srlFooterHeight | dimension | Footer的标准高度 |
srlDragRate | float | 显示拖动高度/真实拖动高度(默认0.5,阻尼效果) |
srlHeaderMaxDragRate | float | Header最大拖动高度/Header标准高度(默认2,要求>=1) |
srlFooterMaxDragRate | float | Footer最大拖动高度/Footer标准高度(默认2,要求>=1) |
srlEnableRefresh | boolean | 是否开启下拉刷新功能(默认true) |
srlEnableLoadmore | boolean | 是否开启加上拉加载功能(默认true) |
srlEnableHeaderTranslationContent | boolean | 拖动Header的时候是否同时拖动内容(默认true) |
srlEnableFooterTranslationContent | boolean | 拖动Footer的时候是否同时拖动内容(默认true) |
srlEnablePreviewInEditMode | boolean | 是否在编辑模式时显示预览效果(默认true) |
srlDisableContentWhenRefresh | boolean | 是否在刷新的时候禁止内容的一切手势操作(默认false) |
srlDisableContentWhenLoading | boolean | 是否在加载的时候禁止内容的一切手势操作(默认false) |
名称-name | 格式-format | 描述-description |
---|---|---|
setPrimaryColors | colors | 主题\强调颜色 |
setPrimaryColorsId | colors | 主题\强调颜色资源Id |
setReboundDuration | integer | 释放后回弹动画时长 |
setHeaderHeight | dimension | Header的标准高度(px/dp 两个版本) |
setFooterHeight | dimension | Footer的标准高度(px/dp 两个版本) |
setDragRate | float | 显示拖动高度/真实拖动高度(默认0.5,阻尼效果) |
setHeaderMaxDragRate | float | Header最大拖动高度/Header标准高度(默认2,要求>=1) |
setFooterMaxDragRate | float | Footer最大拖动高度/Footer标准高度(默认2,要求>=1) |
setEnableRefresh | boolean | 是否开启下拉刷新功能(默认true) |
setEnableLoadmore | boolean | 是否开启加上拉加载功能(默认true) |
setEnableHeaderTranslationContent | boolean | 拖动Header的时候是否同时拖动内容(默认true) |
setEnableFooterTranslationContent | boolean | 拖动Footer的时候是否同时拖动内容(默认true) |
setEnableAutoLoadmore | boolean | 是否监听列表滚动到底部时触发加载事件 |
setDisableContentWhenRefresh | boolean | 是否在刷新的时候禁止内容的一切手势操作(默认false) |
setDisableContentWhenLoading | boolean | 是否在加载的时候禁止内容的一切手势操作(默认false) |
setReboundInterpolator | Interpolator | 设置回弹动画的插值器 |
setRefreshHeader | RefreshHeader | 设置指定的Header |
setRefreshFooter | RefreshFooter | 设置指定的Footer |
setOnRefreshListener | OnRefreshListener | 设置刷新监听器 |
setOnLoadmoreListener | OnLoadmoreListener | 设置加载监听器 |
setOnRefreshLoadmoreListener | OnRefreshLoadmoreListener | 同时设置上面两个监听器 |
setOnMultiPurposeListener | OnMultiPurposeListener | 设置多功能监听器 |
setLoadmoreFinished | boolean | 设置全部数据加载完成,之后不会触发加载事件 |
finishRefresh | (int delayed) | 完成刷新,结束刷新动画 |
finishLoadmore | (int delayed) | 完成加载,结束加载动画 |
getRefreshHeader | RefreshHeader | 获取Header |
getRefreshFooter | RefreshFooter | 获取Footer |
getState | RefreshState | 获取当前状态 |
isRefreshing | boolean | 是否正在刷新 |
isLoading | boolean | 是否正在加载 |
autoRefresh | (int delayed) | 触发自动刷新 |
autoLoadmore | (int delayed) | 触发自动加载 |
package db.lanxing.damexshixu.ui.frament2;
import android.Manifest;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.recker.flybanner.FlyBanner;
import com.scwang.smartrefresh.layout.footer.ClassicsFooter;
import com.squareup.picasso.Picasso;
import com.umeng.socialize.ShareAction;
import com.umeng.socialize.UMAuthListener;
import com.umeng.socialize.UMShareAPI;
import com.umeng.socialize.UMShareListener;
import com.umeng.socialize.bean.SHARE_MEDIA;
import com.umeng.socialize.media.UMImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import db.lanxing.damexshixu.R;
import db.lanxing.damexshixu.adapter.MyRecAdapter;
import db.lanxing.damexshixu.dao.MyBeanDao;
import db.lanxing.damexshixu.data.ApiService;
import db.lanxing.damexshixu.data.App;
import db.lanxing.damexshixu.data.Bean;
import db.lanxing.damexshixu.data.Constans;
import db.lanxing.damexshixu.data.MyBean;
import db.lanxing.damexshixu.ui.activity.MainActivity;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.google.gson.Gson;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.constant.SpinnerStyle;
import com.scwang.smartrefresh.layout.footer.BallPulseFooter;
import com.scwang.smartrefresh.layout.header.ClassicsHeader;
import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import butterknife.BindView;
import butterknife.ButterKnife;
import db.myrecy.R;
import db.myrecy.adapter.MyAdapter;
import db.myrecy.utils.dao.StudentsDao;
import db.myrecy.data.bean.Bean;
import db.myrecy.data.bean.MyBean;
import db.myrecy.data.common.Constant;
import db.myrecy.utils.dbutil.App;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.tbr)
Toolbar tbr;
@BindView(R.id.rcw)
RecyclerView rcw;
@BindView(R.id.refreshLayout)
SmartRefreshLayout refreshLayout;
private List list;
private List myBeans = new ArrayList<>();
private MyAdapter adapter;
private int size;
private int count;
private Intent intent;
private StudentsDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
dao = App.getDB(this);
initData();
initDataHttp();
}
private void initDataHttp() {
Volley.newRequestQueue(this).add(new StringRequest(Request.Method.POST, Constant.URL, new Response.Listener() {
@Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map getParams() throws AuthFailureError {
return super.getParams();
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == 1) {
startActivityForResult(new Intent(MainActivity.this, AddActivity.class), 11);
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(1, 1, 1, "添加数据");
return super.onCreateOptionsMenu(menu);
}
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
if (adapter == null) {
Toast.makeText(MainActivity.this, "没有数据数据", Toast.LENGTH_SHORT).show();
return;
} else {
count = adapter.getItemCount();
}
if (adapter.getItemCount() == size) {
Toast.makeText(MainActivity.this, "没有更多了", Toast.LENGTH_SHORT).show();
}
if (count + 5 < size) {
for (int i = count; i < count + 5; i++) {
getMyBean(i);
}
} else {
for (int i = count; i < size; i++) {
getMyBean(i);
}
}
adapter.notifyDataSetChanged();
}
};
private List images;
private void initData() {
setSupportActionBar(tbr);
rcw.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
Volley.newRequestQueue(this).add(new StringRequest(Constant.URL, new Response.Listener() {
@Override
public void onResponse(String response) {
list = new Gson().fromJson(response, Bean.class).getResults();
size = list.size();
for (int i = count; i < 2; i++) {
getMyBean(i);
}
adapter = new MyAdapter(R.layout.item, myBeans);
rcw.setAdapter(adapter);
initListener();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}));
简单的使用
public class Adapter1 extends BaseQuickAdapter{
Context mcontext;
public Adapter1(Context context,int layoutResId, @Nullable List data) {
super(layoutResId, data);
mcontext=context;
}
@Override
protected void convert(BaseViewHolder helper, Student item) {
helper.setText(R.id.student_name,item.getName())
.setText(R.id.student_age,item.getAge()+"")
.setText(R.id.student_address,item.getAddress());
Glide.with(mcontext).load(item.getIcon()).into((ImageView) helper.getView(R.id.student_icon));
}
}
从上文中的实例代码我们可以看出以下几点:
1、使用: 首先需要继承BaseQuickAdapter,然后BaseQuickAdapter 《Bean,BaseViewHolder》 第一个泛型Bean是数据实体类型,第二个BaseViewHolder是ViewHolder其目的是为了支持扩展ViewHolder。
2、赋值:可以直接使用viewHolder对象点相关方法通过传入viewId和数据进行,方法支持链式调用。如果是加载网络图片或自定义view可以通过viewHolder.getView(viewId)获取该控件。
添加Item事件
item的点击事件和长按事件已经封装到adapter里面,只需要在使用的时候用就可以了。
adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
Toast.makeText(CommonAdapterActivity.this, "点击了item", Toast.LENGTH_SHORT).show();
}
});
Item的长按事件
adapter.setOnItemLongClickListener(new BaseQuickAdapter.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
Toast.makeText(CommonAdapterActivity.this, "长按了item", Toast.LENGTH_SHORT).show();
return false;
}
});
注意:嵌套recycleView的情况下需要使用你使用 adapter. setOnItemClickListener 来设置点击事件,如果使用recycleView.addOnItemTouchListener会累计添加的。
添加Item子控件点击事件
首先在adapter的convert方法里面通过viewHolder.addOnClickListener绑定一下的控件id,
@Override
protected void convert(BaseViewHolder helper, Student item) {
helper.setText(R.id.student_name,item.getName())
.setText(R.id.student_age,item.getAge()+"")
.setText(R.id.student_address,item.getAddress())
.addOnClickListener(R.id.student_icon)
.addOnClickListener(R.id.student_name)
.addOnLongClickListener(R.id.student_address);
Glide.with(mcontext).load(item.getIcon()).into((ImageView) helper.getView(R.id.student_icon));
}
然后在设置子控件点击事件
adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
switch (view.getId()) {
case R.id.student_icon:
//获取其他控件,如下,获取student_name
TextView textView=(TextView) adapter.getViewByPosition(recycleview, position, R.id.student_name);
Toast.makeText(CommonAdapterActivity.this, "点击"+textView.getText().toString()+"的头像", Toast.LENGTH_SHORT).show();
break;
case R.id.student_name:
Toast.makeText(CommonAdapterActivity.this, "点击了名字", Toast.LENGTH_SHORT).show();
break;
}
}
});
然后在设置子控件长按事件
adapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() {
@Override
public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
if (view.getId() == R.id.student_address)
Toast.makeText(CommonAdapterActivity.this, "长按了address", Toast.LENGTH_SHORT).show();
return false;
}
});
注意:设置子控件的事件,如果不在adapter中绑定,点击事件无法生效,因为无法找到你需要设置的控件。
如果需要获取item中其他控件,上述代码有表现, adapter.getViewByPosition()方法进行初始化
TextView textView=(TextView) adapter.getViewByPosition(recycleview, position, R.id.student_name);
ps:如果有header的话需要处理一下position加上 headerlayoutcount。即如果header有的话,postion的点击postion实际上为postion+headerlayoutcount.
动画
开启动画(默认为渐显效果)
adapter.openLoadAnimation();
默认提供5种方法(渐显、缩放、从下到上,从左到右、从右到左)
public static final int ALPHAIN = 0x00000001;
public static final int SCALEIN = 0x00000002;
public static final int SLIDEIN_BOTTOM = 0x00000003;
public static final int SLIDEIN_LEFT = 0x00000004;
public static final int SLIDEIN_RIGHT = 0x00000005;
切换动画
quickAdapter.openLoadAnimation(BaseQuickAdapter.ALPHAIN);
自定义动画
quickAdapter.openLoadAnimation(new BaseAnimation() {
@Override
public Animator[] getAnimators(View view) {
return new Animator[]{
ObjectAnimator.ofFloat(view, "scaleY", 1, 1.1f, 1),
ObjectAnimator.ofFloat(view, "scaleX", 1, 1.1f, 1)
};
}
});
动画默认只执行一次,如果想重复执行可设置
mQuickAdapter.isFirstOnly(false);
因为有些人不希望第一页看到动画,或者说希望前几个条目加载不需要有动画,所以可以
设置不显示动画数量
adapter.setNotDoAnimationCount(count);
添加头部、尾部
mQuickAdapter.addHeaderView(getView());
mQuickAdapter.addFooterView(getView());
删除指定view
mQuickAdapter.removeHeaderView(getView);
mQuickAdapter.removeFooterView(getView);
删除所有
mQuickAdapter.removeAllHeaderView();
mQuickAdapter.removeAllFooterView();
默认出现了头部就不会显示Empty,和尾部,配置以下方法也支持同时显示:
setHeaderAndEmpty
setHeaderFooterEmpty
默认头部尾部都是占满一行,如果需要不占满可以配置:
setHeaderViewAsFlow
setFooterViewAsFlow
加载更多
此adapter封装加载更多其实并不好用,因此我更建议采用传统的根据recyclerview判断item位置进行判断,自动加载更多
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
firstVisibleItem=linearLayoutManager.findFirstVisibleItemPosition();
if (newState == RecyclerView.SCROLL_STATE_IDLE&&linearLayoutManager.getItemCount() >0&&lastVisibleItem + 1 == linearLayoutManager.getItemCount()) {
new Handler().postDelayed(() -> loadData(),300) ;
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
firstVisibleItem=linearLayoutManager.findFirstVisibleItemPosition();
}
});
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
```
屏幕中最后一个可见子项的position
int lastVisibleItem = layoutManager.findLastVisibleItemPosition();
“`
//当前屏幕所看到的子项个数
layoutManager.getChildCount();
//当前RecyclerView的所有子项个数
layoutManager.getItemCount();
//RecyclerView的滑动状态
recyclerView.getScrollState();
sw.setRefreshHeader(new DeliveryHeader(this));//降落伞
// sw.setRefreshHeader(new WaveSwipeHeader(this));//水滴下落
// sw.setRefreshHeader(new WaterDropHeader(this));//水滴上浮
// sw.setRefreshHeader(new FunGameBattleCityHeader(this));//打仗坦克小游戏
// sw.setRefreshHeader(new FunGameHitBlockHeader(this));//弹弹球
// sw.setRefreshHeader(new DropboxHeader(this));//掉落盒子
sw.setRefreshHeader(new BezierRadarHeader(this));//贝塞尔雷达
// sw.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale));//三点移动
sw.setRefreshFooter(new BallPulseFooter(this));
sw.setReboundDuration(100);//回弹
sw.setScrollBarFadeDuration(100);//滚动条消失
sm.setRefreshHeader(new ClassicsHeader(this));
// 设置 Footer 为 球脉冲 样式
sm.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale));
sm.setRefreshFooter(new ClassicsFooter(this).setSpinnerStyle(SpinnerStyle.Scale));
sm.setReboundDuration(100);
sm.setScrollBarFadeDuration(100);
sm.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(sm sm) {
handler.postDelayed(runnable, 10);
sm.finishRefresh(1000/*,false*/);
// 传入false表示刷新失败
}
});
sm.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore(sm sm) {
handler.postDelayed(runnable, 10);
Toast.makeText(MainActivity.this, "加载完成", Toast.LENGTH_SHORT).show();
sm.finishLoadMore(1000/*,false*/);
// 传入false表示加载失败
}
});
}
private void initListener() {
adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
private Button n;
private Button y;
private TextView title;
private View inflate;
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, final int position) {
final PopupWindow window = new PopupWindow();
window.setWidth(RecyclerView.LayoutParams.WRAP_CONTENT);
window.setHeight(RecyclerView.LayoutParams.WRAP_CONTENT);
window.setOutsideTouchable(true);
window.setBackgroundDrawable(new ColorDrawable());
inflate = View.inflate(MainActivity.this, R.layout.popu, null);
title = inflate.findViewById(R.id.title);
n = inflate.findViewById(R.id.n);
y = inflate.findViewById(R.id.y);
title.setText("是否添加数据库?");
y.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, DBActivity.class);
intent.putExtra("key", myBeans.get(position));
startActivity(intent);
}
});
n.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
window.dismiss();
}
});
window.setContentView(inflate);
window.showAsDropDown(view);
}
});
}
private void getMyBean(int i) {
if (list != null) {
if (list.get(i).getImages() != null) {
images = list.get(i).getImages();
} else {
images = null;
}
myBeans.add(new MyBean(list.get(i).getUrl(), images, list.get(i).getCreatedAt(), list.get(i).getDesc()));
}
}
}
import android.support.annotation.Nullable;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.recker.flybanner.FlyBanner;
import java.util.List;
import db.myrecy.R;
import db.myrecy.data.bean.MyBean;
/**
* Created by Lenovo on 2018/06/04.
*/
public class MyAdapter extends BaseQuickAdapter {
public MyAdapter(int layoutResId, @Nullable List data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, MyBean item) {
helper.setText(R.id.time,item.getTime());
helper.setText(R.id.content,item.getContent());
WebView webView= helper.getView(R.id.wvw);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(item.getUrl());
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
FlyBanner fbnr= helper.getView(R.id.fbnr);
if(item.getImgs()!=null){
fbnr.setImagesUrl(item.getImgs());
fbnr.startAutoPlay();
}
}
}