Android ScrollView实现向上滑动控件顶部悬浮效果

本文参考了: 《上滑停靠顶端的悬浮框》的代码,在此表示感谢。【上滑停靠顶端的悬浮框】里的实现方法是使用两个控件,滑动时,监听ScrollView的滚动Y值,从而通过对两个控件的显示隐藏来实现控件的顶部悬浮。但是实际应用场景中,有可能需要悬浮的控件里面的内容是比较多的,如果通过显示隐藏的方式来实现的话,操作控件里的内容时,需要重复定义两套变量,对控件里的内容进行修改时也是要操作再次,非常麻烦。

本文的方法是通过addView和removeView来实现的。

一、首先让ScrollView实现滚动监听:

package com.willen.topFloatDemo; 

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView; 

/**
 * ScrollView并没有实现滚动监听,所以我们必须自行实现对ScrollView的监听,
 * 我们很自然的想到在onTouchEvent()方法中实现对滚动Y轴进行监听
 * ScrollView的滚动Y值进行监听
 */
public class MyScrollView extends ScrollView {
 private OnScrollListener onScrollListener;
 /**
 * 主要是用在用户手指离开MyScrollView,MyScrollView还在继续滑动,我们用来保存Y的距离,然后做比较
 */
 private int lastScrollY; 

 public MyScrollView(Context context) {
 super(context, null);
 }
 public MyScrollView(Context context, AttributeSet attrs) {
 super(context, attrs, 0);
 }
 public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 }
 /**
 * 设置滚动接口
 * @param onScrollListener
 */
 public void setOnScrollListener(OnScrollListener onScrollListener){
 this.onScrollListener = onScrollListener;
 }
 /**
 * 用于用户手指离开MyScrollView的时候获取MyScrollView滚动的Y距离,然后回调给onScroll方法中
 */
 private Handler handler = new Handler() { 

 public void handleMessage(android.os.Message msg) {
  int scrollY = MyScrollView.this.getScrollY(); 

  //此时的距离和记录下的距离不相等,在隔5毫秒给handler发送消息
  if(lastScrollY != scrollY){
  lastScrollY = scrollY;
  handler.sendMessageDelayed(handler.obtainMessage(), 5);
  }
  if(onScrollListener != null){
  onScrollListener.onScroll(scrollY);
  } 

 }; 

 };
 /**
 * 重写onTouchEvent, 当用户的手在MyScrollView上面的时候,
 * 直接将MyScrollView滑动的Y方向距离回调给onScroll方法中,当用户抬起手的时候,
 * MyScrollView可能还在滑动,所以当用户抬起手我们隔5毫秒给handler发送消息,在handler处理
 * MyScrollView滑动的距离
 */
 @Override
 public boolean onTouchEvent(MotionEvent ev) {
 if(onScrollListener != null){
  onScrollListener.onScroll(lastScrollY = this.getScrollY());
 }
 switch(ev.getAction()){
 case MotionEvent.ACTION_UP:
  handler.sendMessageDelayed(handler.obtainMessage(), 20);
  break;
 }
 return super.onTouchEvent(ev);
 } 

 /**
 * 滚动的回调接口
 */
 public interface OnScrollListener{
 /**
  * 回调方法, 返回MyScrollView滑动的Y方向距离
  */
 public void onScroll(int scrollY);
 }
} 

二、定义简单布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/container"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" > 

 <com.willen.topFloatDemo.MyScrollView
 android:id="@+id/myScrollView"
 android:layout_width="match_parent"
 android:layout_height="match_parent" > 

 <LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical" > 

  <RelativeLayout
  android:id="@+id/rlayout"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal" > 

  <TextView
   android:id="@+id/tv"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:gravity="center_vertical"
   android:text="顶部信息\n顶部信息\n顶部信息\n顶部信息"
   android:textSize="40dp" />
  </RelativeLayout> 

  <LinearLayout
  android:id="@+id/search02"
  android:layout_width="match_parent"
  android:layout_height="40dip"
  android:orientation="vertical" > 

  <EditText
   android:id="@+id/search_edit"
   android:layout_width="match_parent"
   android:layout_height="40dip"
   android:background="@drawable/bg_edittext"
   android:hint="请输入..."
   android:padding="5dip"
   android:singleLine="true"
   android:textColorHint="#AAAAAA"
   android:textSize="15dip" />
  </LinearLayout> 

  <TextView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:gravity="center_horizontal"
  android:text="测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容\n测试内容"
  android:textSize="40dp" />
 </LinearLayout>
 </com.willen.topFloatDemo.MyScrollView> 

 <LinearLayout
 android:id="@+id/search01"
 android:layout_width="match_parent"
 android:layout_height="40dip"
 android:orientation="vertical" >
 </LinearLayout> 

</RelativeLayout> 

三、MainActivity

package com.willen.topFloatDemo; 

import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout; 

import com.willen.topFloatDemo.MyScrollView.OnScrollListener; 

public class MainActivity extends Activity implements OnScrollListener{
 private EditText search_edit;
 private MyScrollView myScrollView;
 private int searchLayoutTop; 

 LinearLayout search01,search02;
 RelativeLayout rlayout; 

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 //初始化控件
 init();
 } 

 private void init() {
 search_edit = (EditText)findViewById(R.id.search_edit);
 myScrollView = (MyScrollView)findViewById(R.id.myScrollView);
 search01 = (LinearLayout)findViewById(R.id.search01);
 search02 = (LinearLayout)findViewById(R.id.search02);
 rlayout = (RelativeLayout)findViewById(R.id.rlayout);
 myScrollView.setOnScrollListener(this); 

 } 

 @Override
 public void onWindowFocusChanged(boolean hasFocus) {
 super.onWindowFocusChanged(hasFocus);
 if(hasFocus){
  searchLayoutTop = rlayout.getBottom();//获取searchLayout的顶部位置
 }
 } 

 //监听滚动Y值变化,通过addView和removeView来实现悬停效果
 @Override
 public void onScroll(int scrollY) {
 if(scrollY >= searchLayoutTop){
  if (search_edit.getParent()!=search01) {
  search02.removeView(search_edit);
  search01.addView(search_edit);
  }
 }else{
  if (search_edit.getParent()!=search02) {
  search01.removeView(search_edit);
  search02.addView(search_edit);
  }
 }
 }
}

代码中均有注释,应该不用再多解释了。

本文源码下载:Android实现向上滑动控件顶部悬浮效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android RecycleView使用(CheckBox全选、反选、单选)

    本文实例为大家分享了CheckBox全选.反选.单选的具体代码,供大家参考,具体内容如下 MainActiivity package com.bwie.day06; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.Recyc

  • Android 实现控件悬浮效果实例代码

    随着移动互联网的快速发展,它已经和我们的生活息息相关了,在公交地铁里面都能看到很多人的人低头看着自己的手机屏幕,从此"低头族"一词就产生了,作为一名移动行业的开发人员,我自己也是一名"低头族",上下班时间在公交地铁上看看新闻来打发下时间,有时候也会看看那些受欢迎的App的一些界面效果,为什么人家的app那么受欢迎?跟用户体验跟UI设计也有直接的关系,最近在美团和大众点评的App看到如下效果,我感觉用户好,很人性化,所以自己也尝试着实现了下,接下来就讲解下实现思路!

  • 浅谈Android应用内悬浮控件实践方案总结

    在工作中遇到一个需求,需要在整个应用的上层悬浮显示控件,目标效果如下图: 首先想到的是申请悬浮窗权限,OK~ 打开搜索引擎,映入眼帘的并不是如何申请,而是"Android 悬浮窗权限各机型各系统适配大全.Android 绕过权限显示悬浮窗...",为什么悬浮窗权限会有这么多坑呢?悬浮窗可以在桌面显示,被恶意软件用来偷偷弹广告怎么办?作为一个系统级别的特殊权限,这是它应有的高傲 - - 正确引导用户打开悬浮窗权限才是标准做法,若这就是定论的话这篇文章也没必要写了,我们绕过悬浮窗权限直接去

  • Android自定义覆盖层控件 悬浮窗控件

    在我们移动应用开发过程中,偶尔有可能会接到这种需求: 1.在手机桌面创建一个窗口,类似于360的悬浮窗口,点击这个窗口可以响应(至于窗口拖动我们可以后面再扩展). 2.自己开发的应用去启动一个非本应用B,在B应用的某个界面增加一个引导窗口. 3.在应用的页面上触发启动这个窗口,该窗口悬浮在这个页面上,但又不会影响界面的其他操作.即不像PopupWindow那样要么窗口消失要么页面不可响应 以上需求都有几个共同特点,1.窗口的承载页面不一定不是本应用页面(Activity),即不是类似dialog

  • Android开发之基于RecycleView实现的头部悬浮控件

    RecyclerView是一种类似于ListView的一个滑动列表,但是RecyclerView和ListView相比,RecyclerView比ListView更好,RecyclerView支持横向滑动,RecyclerView没有点击事件,需要自己加入,还可以做出各种炫酷的效果动画,更符合高内聚低耦合, 前言 前几天看到一个RecycleView中筛选框滑动可以悬浮在头部的效果类似商机盒子中的商机模块. 本来想法很常规 通过Recycview装饰器来实现(刚开始是否定掉的感觉太难) 通过Re

  • Android使用RecycleView实现拖拽交换item位置

    本文实例为大家分享了RecycleView实现拖拽交换item位置的具体代码,供大家参考,具体内容如下 老规矩,先来一张效果图: 相比起ListView而言,RecycleView实现拖拽交换位置的效果要简单很多,因为通过SDK中的ItemTouchHelper工具类可以轻松的实现这种效果,并且一套代码支持所有布局方式;而ListView的话则需要通过生成View的缓存镜像设置到ImageView中,然后通过WindowManager来操作该ImageView,具体怎么实现这里就不展开讲解了.回

  • Android 中RecycleView实现item的点击事件

    Android 中RecycleView实现item的点击事件 RecycleView现在已经越来越受到大家的重视,因为他既可以代替listView还可以代替GridView,但是RecycleView本身不不像ListView那样具有setOnItemClickListener,这个关于子item的点击,但是我们往往会用到RecycleView并且希望他的自孩子可以被点击,那么如何实现他的item的点击事件呢? 首先我们在RecyclerView.ViewHolder中的实现: public

  • Android ScrollView实现向上滑动控件顶部悬浮效果

    本文参考了: <上滑停靠顶端的悬浮框>的代码,在此表示感谢.[上滑停靠顶端的悬浮框]里的实现方法是使用两个控件,滑动时,监听ScrollView的滚动Y值,从而通过对两个控件的显示隐藏来实现控件的顶部悬浮.但是实际应用场景中,有可能需要悬浮的控件里面的内容是比较多的,如果通过显示隐藏的方式来实现的话,操作控件里的内容时,需要重复定义两套变量,对控件里的内容进行修改时也是要操作再次,非常麻烦. 本文的方法是通过addView和removeView来实现的. 一.首先让ScrollView实现滚动

  • Android ScrollView嵌套横向滑动控件时冲突问题

    前言:今天在开发的时候遇到这样的问题,最外层是ScrollView,里面嵌套了一个横向滑动的日历控件,在滑动日历的时候很卡顿.看到这种问题,自然而然的就会想到scrollview和其他可滑动控件的冲突问题. 解决思路 用户的左右滑动操作被最外层的scrollView控件处理掉了,所以只要让scrollview对左右滑动事件不监听,让其子控件处理左右滑动事件 .重写scrollview的onInterceptTouchEvent方法,当上下滑动时不处理即可. 代码如下 public void se

  • Android实现IOS相机滑动控件

    IOS相比于Android,动画效果是一方面优势,IOS相机切换时滑动的动画很不错,看着是有一个3D的效果,而且变化感觉很自然.Android也可以通过Graphics下面的Camera可以实现3D效果,开始尝试着用这个做了一下,效果不理想,滑动之后各组文字之间的距离就变了,从立体空间来说这是合逻辑的,但是看着很别捏.IOS相机的滑动效果文字之间的间隔在滑动的时候是不变的. 后面通过调整TextView X方向的scale使文字看着紧凑一点,然后通过计算的距离的方式,在滑动的时候保持各组文字之间

  • Android自定义双向滑动控件

    本文实例为大家分享了Android自定义双向滑动控件的具体代码,供大家参考,具体内容如下 先看一下效果图 1.SeekBarPressure工具类 public class SeekBarPressure extends View {     private static final String TAG = "SeekBarPressure";     private static final int CLICK_ON_LOW = 1;      //点击在前滑块上     priv

  • Android自定义View实现随手势滑动控件

    本文控件为大家分享了Android随手势滑动控件的具体代码,供大家参考,具体内容如下 1.新建自定义控件类:MyView public class MyView extends Button{ //记录上次滑动后的坐标值 private int lastX; private int lastY; public MyView(Context context) { super(context); // TODO Auto-generated constructor stub } public MyV

  • Android自定义View之组合控件实现类似电商app顶部栏

    本文实例为大家分享了Android自定义View之组合控件,仿电商app顶部栏的相关代码,供大家参考,具体内容如下 效果图: 分析:左右两边可以是TextView和Button,设置drawableTop即可,中间的看着像是EditText,但是用过淘宝天猫等类似app的话会发现点击搜索不是在当前Activit进行搜索的,是跳转到另外的页面进行的,所以用TextView然后设置背景即可. 实现流程 参数列表: 设置属性文件:values下建立attrs.xml文件,添加需要自定义的属性. <?x

  • Android开源堆叠滑动控件仿探探效果

    堆叠滑动控件,类似于社交软件探探的效果,并增加以下扩展: 支持滑动方向控制 支持消失方向控制 支持嵌入到ViewPager等滑动控件 支持内嵌ListView,RecycleView等滑动控件 效果演示 如何使用 xml引入StackCardsView: <com.beyondsw.lib.widget.StackCardsView android:id="@+id/cards" android:layout_width="match_parent" andr

  • Android通过ImageView设置手指滑动控件缩放

    ImageView设置手指滑动缩放效果,具体实现步骤大家通过本文学习下吧! 实现步骤 1, imageview设置scaletype为 android:scaleType="matrix" 2, 设置imageview的setOnTouchListener,重写里面的代码 3, 新建一个matrix, matrix.postScale(scale,scale,缩放中心,缩放中心); image.setImageMatrix(matrix); 这样image的大小就会改变了. 需要注意的

  • Android自定义日历滑动控件

    本文实例为大家分享了Android自定义日历滑动控件的使用方法,供大家参考,具体内容如下 最近公司项目需要做这个需求,自己才疏学浅,总算能写出个大概来,遂在这里记录下来. 分析 先来分析一下: 首先,我们的需求是可以左右点击查看跳转到下一个月,中间的日历控件可以水平滚动选择日期,所以我们中间的日历控件用一个RecycleView来做,左右两位的为ImageVeiw. LRCalendarView 总体流程: 编写LRCalendarView的布局R.layout.calendar_view 新建

  • 总结Android中MD风格相关控件

    要使用MD风格控件,首先需要在Gradle中加入Support Design Library,例如: compile 'com.android.support:design:24.1.1' 一.CoordinatorLayout 1.CoordinatorLayout + AppBarLayout 布局文件代码如下: <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.

随机推荐