技术标签: android snaphelper循环
代码已经整理好,效果如下图:
GravitySnapHelper:/*
* Copyright (C) 2016 The Android Open Source Project
* Copyright (C) 2016 Rúben Sousa
*
* 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
*
* 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.
* See the License for the specific languag`e governing permissions and
* limitations under the License.
*/
package com.haiersmart.sfnation.widget;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSnapHelper;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.View;
import com.haiersmart.sfnation.R;
public class GravitySnapHelper extends LinearSnapHelper {
private OrientationHelper mVerticalHelper;
private OrientationHelper mHorizontalHelper;
private int mGravity;
private boolean mIsRtlHorizontal;
private boolean mSnapLastItemEnabled;
SnapListener mSnapListener;
boolean mSnapping;
private RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_SETTLING) {
mSnapping = false;
}
if (newState == RecyclerView.SCROLL_STATE_IDLE && mSnapping && mSnapListener != null) {
int position = getSnappedPosition(recyclerView);
if (position != RecyclerView.NO_POSITION) {
mSnapListener.onSnap(position);
}
mSnapping = false;
}
}
};
public GravitySnapHelper(int gravity) {
this(gravity, false, null);
}
public GravitySnapHelper(int gravity, boolean enableSnapLastItem) {
this(gravity, enableSnapLastItem, null);
}
public GravitySnapHelper(int gravity, boolean enableSnapLastItem, SnapListener snapListener) {
if (gravity != Gravity.START && gravity != Gravity.END
&& gravity != Gravity.BOTTOM && gravity != Gravity.TOP) {
throw new IllegalArgumentException("Invalid gravity value. Use START " +
"| END | BOTTOM | TOP constants");
}
mSnapListener = snapListener;
mGravity = gravity;
mSnapLastItemEnabled = enableSnapLastItem;
}
@Override
public void attachToRecyclerView(@Nullable RecyclerView recyclerView)
throws IllegalStateException {
if (recyclerView != null) {
if (mGravity == Gravity.START || mGravity == Gravity.END) {
mIsRtlHorizontal
= recyclerView.getContext().getResources().getBoolean(R.bool.is_rtl);
}
if (mSnapListener != null) {
recyclerView.addOnScrollListener(mScrollListener);
}
}
super.attachToRecyclerView(recyclerView);
}
@Override
public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager,
@NonNull View targetView) {
int[] out = new int[2];
if (layoutManager.canScrollHorizontally()) {
if (mGravity == Gravity.START) {
out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager), false);
} else { // END
out[0] = distanceToEnd(targetView, getHorizontalHelper(layoutManager), false);
}
} else {
out[0] = 0;
}
if (layoutManager.canScrollVertically()) {
if (mGravity == Gravity.TOP) {
out[1] = distanceToStart(targetView, getVerticalHelper(layoutManager), false);
} else { // BOTTOM
out[1] = distanceToEnd(targetView, getVerticalHelper(layoutManager), false);
}
} else {
out[1] = 0;
}
return out;
}
@Override
public View findSnapView(RecyclerView.LayoutManager layoutManager) {
View snapView = null;
if (layoutManager instanceof LinearLayoutManager) {
switch (mGravity) {
case Gravity.START:
snapView = findStartView(layoutManager, getHorizontalHelper(layoutManager));
break;
case Gravity.END:
snapView = findEndView(layoutManager, getHorizontalHelper(layoutManager));
break;
case Gravity.TOP:
snapView = findStartView(layoutManager, getVerticalHelper(layoutManager));
break;
case Gravity.BOTTOM:
snapView = findEndView(layoutManager, getVerticalHelper(layoutManager));
break;
}
}
mSnapping = snapView != null;
return snapView;
}
/**
* Enable snapping of the last item that's snappable.
* The default value is false, because you can't see the last item completely
* if this is enabled.
*
* @param snap true if you want to enable snapping of the last snappable item
*/
public void enableLastItemSnap(boolean snap) {
mSnapLastItemEnabled = snap;
}
private int distanceToStart(View targetView, OrientationHelper helper, boolean fromEnd) {
if (mIsRtlHorizontal && !fromEnd) {
return distanceToEnd(targetView, helper, true);
}
return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
}
private int distanceToEnd(View targetView, OrientationHelper helper, boolean fromStart) {
if (mIsRtlHorizontal && !fromStart) {
return distanceToStart(targetView, helper, true);
}
return helper.getDecoratedEnd(targetView) - helper.getEndAfterPadding();
}
/**
* Returns the first view that we should snap to.
*
* @param layoutManager the recyclerview's layout manager
* @param helper orientation helper to calculate view sizes
* @return the first view in the LayoutManager to snap to
*/
private View findStartView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
// We should return the child if it's visible width
// is greater than 0.5 of it's total width.
// In a RTL configuration, we need to check the start point and in LTR the end point
if (mIsRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
}
// If we're at the end of the list, we shouldn't snap
// to avoid having the last item not completely visible.
boolean endOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (mSnapLastItemEnabled && endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
// If the child wasn't returned, we need to return
// the next view close to the start.
return layoutManager.findViewByPosition(firstChild + 1);
}
}
return null;
}
private View findEndView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (mIsRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
}
// If we're at the start of the list, we shouldn't snap
// to avoid having the first item not completely visible.
boolean startOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition() == 0;
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (mSnapLastItemEnabled && startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
// If the child wasn't returned, we need to return the previous view
return layoutManager.findViewByPosition(lastChild - 1);
}
}
return null;
}
int getSnappedPosition(RecyclerView recyclerView) {
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
if (mGravity == Gravity.START || mGravity == Gravity.TOP) {
return ((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition();
} else if (mGravity == Gravity.END || mGravity == Gravity.BOTTOM) {
return ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition();
}
}
return RecyclerView.NO_POSITION;
}
private OrientationHelper getVerticalHelper(RecyclerView.LayoutManager layoutManager) {
if (mVerticalHelper == null) {
mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
}
return mVerticalHelper;
}
private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager) {
if (mHorizontalHelper == null) {
mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
}
return mHorizontalHelper;
}
public interface SnapListener {
void onSnap(int position);
}
}
build.gradlecompile 'com.android.support:design:25.0.0'
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:recyclerview-v7:25.0.0'
compile 'com.android.support:cardview-v7:25.0.0'
方法调用:recycler_view1.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
SnapHelper snapHelperStart = new GravitySnapHelper(Gravity.TOP);
snapHelperStart.attachToRecyclerView(recycler_view1);
地址:
JWT1. JWT是什么JSON Web Token (JWT),它是目前最流行的跨域身份验证解决方案。JWT的精髓在于:“去中心化”,数据是保存在客户端的。JWT的优点1,jwt基于json,非常方便解析。2,可以在令牌钟定义丰富的内容,容易扩展3,通过非对称加密算法及数字签名技术,jwt防止篡改,安全性高4,资源服务使用jwt可不依赖认证服务即可完成授权缺点:1,jwt令牌较长,占存储空间比较大三个部分组成;用.号隔开。1, Header{“typ”:“JWT”,“alg”
1.Notification(通知)自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大改重构,这让开发者也体会到UserNotifications的易用,功能也变得非常强大。iOS 9 以前的通知1.在调用方法时,有些方法让人很难区分,容易写错方法,这让开发者有时候很苦恼。2.应用在运行时...
本文讲的likely()和unlikely()两个宏,在linux内核代码和一些应用中可常见到它们的身影。实质上,这两个宏是关于GCC编译器内置宏__builtin_expect的使用。顾名思义,likely()指“很有可能”之意,而unlikely()指“不太可能”之意。那么,在实际应用中,它们代表什么?又是怎么使用的呢?下面是一篇外文翻译(加上了本人的一些理解),给出了详细答案。likely()和unlikely()对于linux内核代码,在条件判断语句中经常看到likely()...
实现医院药房药品的一系列管理的源代码源程序:# include //包含文件读写 # include # include //包含strcmp()字符是否相等 #include //包含system("cls")清屏#define MAX 60 //下列字符数组的大小 struct Date{//日期 char year[MAX];//年 char month[MAX];//月 ...
本系列文章讨论WebView的各种用法以及使用技巧
在深圳,每年的三四月份都是每个公司的大招聘时间,大家都拿完了年终奖,无法抑制住内心的躁动,开始在各种平台上投简历,离职的原因大概分为以下几种:钱不到位,干的累,学不到东西,前两种我就不说了,想走就走吧,至于最后一种,我还是想说说自己的看法的。很多朋友最近都萌生了跳槽的想法,大部分都是觉得自己的待遇不够理想,这也无可厚非,但是这种事必须知己知彼,先考量下自己的能力,你工作几年了?你会哪些很牛逼的...
作为一名前端工程师,在进行web页面开发的时候,可能会遇到这样一种问题:如何使一个元素相对父容器水平垂直居中,也就是所谓的绝对居中呢?这篇文章将会针对这个问题介绍几种常用的方法。谈到这个问题,相信有点经验的同学们可能心里已经有了答案了。不过,这篇文章将会从下面两种不同的应用场景分别阐述如何使用CSS让一个元素绝对居中,元素有明确的高度不知道元素的高度元素有明确的高度这种场景中,我们已经知道需要绝对...
在iOS开发中经常会用到UIlabel来展示一些文字性的内容,但是默认的文字排版会觉得有些挤,为了更美观也更易于阅读我们可以通过某些方法将UIlabel的行间距和字间距按照需要调节。 比如一个Label的默认间距效果是这样:然后用一个封装起来的Category来调整这部分文字的行间距,其中5.0就是我自定义的文字间距:[UILabel changeLineSpaceForLabel:cell.describeLabel WithSpace:5.0];调整后的效果是这样的:这...
1、通过getDay() 方法,可返回表示星期的某一天的数字<script type="text/javascript">var d=new Date()var weekday=new Array(7)weekday[0]="星期天"weekday[1]="星期一"weekday[2]="星期二"weekday[3]="星期三"weekday[4]="
企业微信消息推送CorpID:企业IDAgentID:应用IDSecret:应用密钥2、功能实现3、方法调用4、结果展示
1.多种支付方式痛点分析现状随着移动支付的盛行、市面上存在多种移动支付方式:微信、支付宝、云闪付、数字货币、通联支付等等,不同的客户习惯使用的移动支付方式也有所不同,如果商家为了吸引更多的客户消费,使用的系统需要对接这么多第三方支付及常用的银行系统,对一般商户来说都存在很大的挑战,几乎是不可能实现的,具体表现如下:商户运营:支付渠道多,收银效率低多种支付渠道接入成本高支付渠道零散,收银汇总难度高支付后无交易分析,运营凭感觉。商户运营:线上线下消费数据同步较难;营销玩法
你已经不是小宝宝了,要学会自己找资料了,本文就不过多介绍一些基础细节了,我来说下这个应用的结构首先这个应用包含了Client和Service,也就是客户端和服务端,因为我...