技术标签: android 下拉加载 功能 android 上拉刷新 android 上拉刷新下拉加载
从开源中国控件里而来,并自己改进一些功能
主要用于控制全局的手势是否上拉刷新,正常滑动,下拉加载三种情况.手势控制源头
public class BaseRecyclerRefreshLayout extends SwipeRefreshLayout implements SwipeRefreshLayout.OnRefreshListener {
private RecyclerView mRecycleView;
private int mTouchSlop;
private SuperRefreshLayoutListener listener;
private boolean mIsOnLoading = false;
private boolean mCanLoadMore = true;
private boolean mHasMore = true;
private int mYDown;
private int mLastY;
public BaseRecyclerRefreshLayout(Context context) {
this(context, null);
}
public BaseRecyclerRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
setOnRefreshListener(this);
setColorSchemeResources(R.color.colorAccent); //TODO 设置转圈颜色跟随控件选中颜色
}
@Override
public void onRefresh() {
if (listener != null && !mIsOnLoading) {
listener.onRefreshing();
} else
setRefreshing(false);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
// 初始化ListView对象
if (mRecycleView == null) {
getRecycleView();
}
}
/**
* 获取RecyclerView
*/
private void getRecycleView() {
if (getChildCount() > 0) {
View childView = getChildAt(0);
if (!(childView instanceof RecyclerView)) {
childView = findViewById(R.id.recyclerView); //TODO 只要布局里有id=recyclerView就可以了
}
if (childView != null && childView instanceof RecyclerView) {
mRecycleView = (RecyclerView) childView;
mRecycleView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (canLoad() && mCanLoadMore) { //向下拉,最后一个可见条目,有更多数据标记,不是正在加载,能加载更多
loadData();
}
}
});
}
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mYDown = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
mLastY = (int) event.getRawY();
break;
default:
break;
}
return super.dispatchTouchEvent(event);
}
/**
* 是否可以加载更多, 条件是到了最底部
*
* @return isCanLoad
*/
private boolean canLoad() {
return isScrollBottom() && !mIsOnLoading && isPullUp() && mHasMore;
}
/**
* 如果到了最底部,而且是上拉操作.那么执行onLoad方法
*/
private void loadData() {
if (listener != null) {
setOnLoading(true);
listener.onLoadMore();
}
}
/**
* 是否是上拉操作
*
* @return isPullUp
*/
private boolean isPullUp() {
return (mYDown - mLastY) >= mTouchSlop;
}
/**
* 设置正在加载
*
* @param loading 设置正在加载
*/
public void setOnLoading(boolean loading) {
mIsOnLoading = loading;
if (!mIsOnLoading) {
mYDown = 0;
mLastY = 0;
}
}
/**
* 判断是否到了最底部
*/
private boolean isScrollBottom() {
return (mRecycleView != null && mRecycleView.getAdapter() != null)
&& getLastVisiblePosition() == (mRecycleView.getAdapter().getItemCount() - 1);
}
/**
* 加载结束记得调用
*/
public void onComplete() {
setOnLoading(false);
setRefreshing(false);
mHasMore = true;
}
/**
* 是否可加载更多
*
* @param mCanLoadMore 是否可加载更多
*/
public void setCanLoadMore(boolean mCanLoadMore) {
this.mCanLoadMore = mCanLoadMore;
}
/**
* 获取RecyclerView可见的最后一项
*
* @return 可见的最后一项position
*/
public int getLastVisiblePosition() {
int position;
if (mRecycleView.getLayoutManager() instanceof LinearLayoutManager) {
position = ((LinearLayoutManager) mRecycleView.getLayoutManager()).findLastVisibleItemPosition();
} else if (mRecycleView.getLayoutManager() instanceof GridLayoutManager) {
position = ((GridLayoutManager) mRecycleView.getLayoutManager()).findLastVisibleItemPosition();
} else if (mRecycleView.getLayoutManager() instanceof StaggeredGridLayoutManager) {
StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) mRecycleView.getLayoutManager();
int[] lastPositions = layoutManager.findLastVisibleItemPositions(new int[layoutManager.getSpanCount()]);
position = getMaxPosition(lastPositions);
} else {
position = mRecycleView.getLayoutManager().getItemCount() - 1;
}
return position;
}
/**
* 获得最大的位置
*
* @param positions 获得最大的位置
* @return 获得最大的位置
*/
private int getMaxPosition(int[] positions) {
int maxPosition = Integer.MIN_VALUE;
for (int position : positions) {
maxPosition = Math.max(maxPosition, position);
}
return maxPosition;
}
/**
* 添加加载和刷新
*
* @param listener add the listener for SuperRefreshLayout
*/
public void setSuperRefreshLayoutListener(SuperRefreshLayoutListener listener) {
this.listener = listener;
}
public interface SuperRefreshLayoutListener {
void onRefreshing();
void onLoadMore();
}
}
主要提供别的Fragment继承的,封装一些常用的方法
/**
* Fragment基础类
*/
@SuppressWarnings("WeakerAccess") //弱引用
public abstract class BaseFragment extends Fragment {
protected Context mContext;
protected View mRoot;
protected Bundle mBundle;
protected LayoutInflater mInflater;
private Fragment mFragment;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
@Override
public void onDetach() {
super.onDetach();
mContext = null;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBundle = getArguments();
initBundle(mBundle); //拿到传过来的数据参数
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mRoot != null) { //复用自己本身的View,如果没有就进行重新加载
ViewGroup parent = (ViewGroup) mRoot.getParent();
if (parent != null)
parent.removeView(mRoot);
} else {
mRoot = inflater.inflate(getLayoutId(), container, false);
mInflater = inflater;
// Do something
onBindViewBefore(mRoot);
// Bind view
// Get savedInstanceState
if (savedInstanceState != null)
onRestartInstance(savedInstanceState);
// Init --> 初始化
initWidget(mRoot);
initData();
}
return mRoot;
}
//控制Fragment显示和隐藏
public void addFragment(int frameLayoutId, Fragment fragment) { //应该对Fragment进行管理,使用一个实例Fragment
if (fragment != null) {
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
//已经有过该fragment(没有带参数的),
if (fragment.getArguments() == null && getChildFragmentManager().findFragmentByTag(fragment.getClass().getName()) != null) {
if (mFragment != null && mFragment.getClass().getName().equals(fragment.getClass().getName())) { //添加的是同一个Fragment(不同对象) 不改变
return; // hide和add 为同一个Fragment不同对象
}
if (mFragment != null) {
Fragment fragmentByTag = getChildFragmentManager().findFragmentByTag(fragment.getClass().getName());
fragment = fragmentByTag; //必须进行赋值,不然以后隐藏 mFragment 会进行出错
transaction.hide(mFragment).show(fragmentByTag);
} else {
transaction.add(frameLayoutId, fragment, fragment.getClass().getName());
}
} else { //有参数的fragment不管有没有添加过相同的显示新的fragment
if (mFragment != null) {
if (mFragment.getClass().getName().equals(fragment.getClass().getName())) { //添加的为同一个fragment
transaction.remove(mFragment);
transaction.add(frameLayoutId,fragment,fragment.getClass().g
文章浏览阅读975次。文章目录一、源码,详见地址二、实践篇1、导入依赖项目2、配置添加依赖项目3、把依赖项目设置为兼容的library(错误解决)声明:本教程不收取任何费用,欢迎转载,尊重作者劳动成果,不得用于商业用途,侵权必究!!!大概是在去年12月份写了一篇这样的文章,最近参照来看发现看的有些费劲,因为当时用的Markdown编辑器所以编辑和排版都相对比较麻烦不好观看,所以决定重新写一..._android 如果引用一个项目作为lib
文章浏览阅读97次。这里是修真院后端小课堂,每篇分享文从八个方面深度解析后端知识/技能,本篇分享的是:【Quartz】【修真院Java小课堂】任务调度-Quartz开场语:大家好,我是IT修真院北京分院第32期的学员廖友,一枚正直纯洁善良的Java程序员,今天给大家分享一下,修真院官网Java任务十中的知识点——任务调度-Quartz一、背景介绍:1、任务调度概念任务调度是指基于给定时间点,给定时间间..._quartz毕设参考文献
文章浏览阅读191次。一般情况下,我们安装好了linux系统,都希望通过工具能够进行远程管理,这样可以方便许多,但是有时候却无法通过这些工具连接,主要是由于我们没有安装远程的服务,如ssh及telnet这2个服务!命令方式安装:sudo apt-get install ssh 安装telnet方法:sudo apt-get install telnet Telnet..._linux不能通过工具访问远程
文章浏览阅读174次。在做springboot连接数据库时:方案1:在项目代码-数据库连接URL后,加上 (注意大小写必须一致)?serverTimezone=UTC方案2:在mysql中设置时区,默认为SYSTEM set global time_zone='+8:00'错误原因:使用了Mysql Connector/J 6.x以上的版本,然set global time_zone='+8:0...
文章浏览阅读4.1k次。在Spring Cloud Zuul中,Zuul本身有几个核心过滤器源码如下:其中 ServletDetectionFilter优先级最高 为-3 ,所以最先执行,这个核心过滤器只是做了一个判断当前请求是通过Spring的DispatcherServlet处理运行,还是通过ZuulServlet来处理运行,并把结果放回上下文中。一般般情况下,发送到API网关的外部请求都会被Spring..._zuul网关 file not allowed to upload!
文章浏览阅读3.6k次。该文章的前提是已安装Python(楼主安装版本为64bit的3.7版本),使用PySerial模块,该模块安装前可先安装pip(推荐安装,还可以用于安装其他模块,使用方便)一、安装PIP1、下载安装包,地址为:https://pypi.org/project/pip/#files2、下载完成后将其解压到python目录下:随后,cmd进入该目录下,并进入到pip-19.0..._phthon 脱机安装串口模块
文章浏览阅读3.2k次。据说是mac下才会发生,其实不是的,和播放器的音频解码方式有关,大家在调用write_videofile函数时加上参数audio_codec="aac",改变下声道编码即可_moviepy 音频不加载
文章浏览阅读1.9k次。_无法打开文件“msvcrtd.lib”
文章浏览阅读96次。以上代码包括实验代码,都能在这里找到SillyBoy作者:Pika链接:https://juejin.cn/post/7227029203656867899来源:稀土掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。_动态so
文章浏览阅读1k次。今天遇到了sha的相关函数的应用,随手收集了点有用的资料,以后在看。。。。。。。HA1散列函数是很常用的散列函数,它产生160bit(20字节)长度的散列值。今天,我就来介绍利用OpenSSL现成的API来计算数据的SHA1散列值。先来看OpenSSL的相关API声明: #include unsigned char *SHA_基于openssl实现sha1算法哈希运算
文章浏览阅读4.6k次,点赞10次,收藏32次。PS:本系列笔记将会记录我此次在北京学习Unity开发的总体过程,方便后期写总结,笔记为日更。笔记内容均为 自己理解,不保证每个都对点乘求角度,叉乘求方向比如敌人再附近,点乘可以求出玩家面朝方向和敌人方向的夹角,叉乘可以得出左转还是右转更好的转向敌人Part 1 点乘:数学上的 点乘为 a * b = |a| * |b| * cos(Θ) Unity中的点乘也是如此 点乘结果为 ..._3d游戏中向量叉乘
文章浏览阅读262次。题目链接:http://poj.org/problem?id=3468题目大意:给出n个数的数值Q是对区间a,b的求和C是对区间a,b内的所有数都加上c思路:成段更新,需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新or询问到的时候#include#include#include#include#inc