android snaphelper循环,Android Studio第十八期 - Snaphelper_尹大庆的博客-程序员宅基地

技术标签: 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);

7b82962648d4908a91bc0799bd972017.gif

地址:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_35618933/article/details/117680134

智能推荐

JWT基础_jwt alg_cookie3_1的博客-程序员宅基地

JWT1. JWT是什么JSON Web Token (JWT),它是目前最流行的跨域身份验证解决方案。JWT的精髓在于:“去中心化”,数据是保存在客户端的。JWT的优点1,jwt基于json,非常方便解析。2,可以在令牌钟定义丰富的内容,容易扩展3,通过非对称加密算法及数字签名技术,jwt防止篡改,安全性高4,资源服务使用jwt可不依赖认证服务即可完成授权缺点:1,jwt令牌较长,占存储空间比较大三个部分组成;用.号隔开。1, Header{“typ”:“JWT”,“alg”

iOS 10 资料整理笔记_anqi0114的博客-程序员宅基地

1.Notification(通知)自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大改重构,这让开发者也体会到UserNotifications的易用,功能也变得非常强大。iOS 9 以前的通知1.在调用方法时,有些方法让人很难区分,容易写错方法,这让开发者有时候很苦恼。2.应用在运行时...

likely(x)与unlikely(x)函数,即__builtin_expect的使用_unlikely()函数_隨意的風的博客-程序员宅基地

本文讲的likely()和unlikely()两个宏,在linux内核代码和一些应用中可常见到它们的身影。实质上,这两个宏是关于GCC编译器内置宏__builtin_expect的使用。顾名思义,likely()指“很有可能”之意,而unlikely()指“不太可能”之意。那么,在实际应用中,它们代表什么?又是怎么使用的呢?下面是一篇外文翻译(加上了本人的一些理解),给出了详细答案。likely()和unlikely()对于linux内核代码,在条件判断语句中经常看到likely()...

药房管理程序c语言,源程序(医院药房药品管理系统C++)_魔术方块的博客-程序员宅基地

实现医院药房药品的一系列管理的源代码源程序:# include //包含文件读写 # include # include //包含strcmp()字符是否相等 #include //包含system("cls")清屏#define MAX 60 //下列字符数组的大小 struct Date{//日期 char year[MAX];//年 char month[MAX];//月 ...

WebView基本用法_webview 使用_郭孝星的博客-程序员宅基地

本系列文章讨论WebView的各种用法以及使用技巧

金三银四跳槽季_weixin_30776863的博客-程序员宅基地

在深圳,每年的三四月份都是每个公司的大招聘时间,大家都拿完了年终奖,无法抑制住内心的躁动,开始在各种平台上投简历,离职的原因大概分为以下几种:钱不到位,干的累,学不到东西,前两种我就不说了,想走就走吧,至于最后一种,我还是想说说自己的看法的。很多朋友最近都萌生了跳槽的想法,大部分都是觉得自己的待遇不够理想,这也无可厚非,但是这种事必须知己知彼,先考量下自己的能力,你工作几年了?你会哪些很牛逼的...

随便推点

html水平位置怎么设置,CSS如何使元素水平垂直定位_weixin_39768695的博客-程序员宅基地

作为一名前端工程师,在进行web页面开发的时候,可能会遇到这样一种问题:如何使一个元素相对父容器水平垂直居中,也就是所谓的绝对居中呢?这篇文章将会针对这个问题介绍几种常用的方法。谈到这个问题,相信有点经验的同学们可能心里已经有了答案了。不过,这篇文章将会从下面两种不同的应用场景分别阐述如何使用CSS让一个元素绝对居中,元素有明确的高度不知道元素的高度元素有明确的高度这种场景中,我们已经知道需要绝对...

(转)iOS学习——UIlabel设置行间距和字间距_uilabel 行间距_ElegantHedgehog的博客-程序员宅基地

  在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]="

(二)企业微信消息推送_企业微信推送_Strawberry_ahh的博客-程序员宅基地

企业微信消息推送CorpID:企业IDAgentID:应用IDSecret:应用密钥2、功能实现3、方法调用4、结果展示

聚合支付系统设计_银行架构聚合支付_分布式架构之巅的博客-程序员宅基地

1.多种支付方式痛点分析现状随着移动支付的盛行、市面上存在多种移动支付方式:微信、支付宝、云闪付、数字货币、通联支付等等,不同的客户习惯使用的移动支付方式也有所不同,如果商家为了吸引更多的客户消费,使用的系统需要对接这么多第三方支付及常用的银行系统,对一般商户来说都存在很大的挑战,几乎是不可能实现的,具体表现如下:商户运营:支付渠道多,收银效率低多种支付渠道接入成本高支付渠道零散,收银汇总难度高支付后无交易分析,运营凭感觉。商户运营:线上线下消费数据同步较难;营销玩法

Android物联网(二)—— WIFI通讯_刘桂林的博客-程序员宅基地

你已经不是小宝宝了,要学会自己找资料了,本文就不过多介绍一些基础细节了,我来说下这个应用的结构首先这个应用包含了Client和Service,也就是客户端和服务端,因为我...

推荐文章

热门文章

相关标签