标签:
Android ScrollView向上滑动控件顶部悬浮效果实现 * 导航栏实现悬浮置顶效果(顶部图片隐藏,下面的单选框导航悬浮)
【上滑停靠顶端的悬浮框】里的实现方法是使用两个控件,滑动时,监听ScrollView的滚动Y值, * 从而通过对两个控件的显示隐藏来实现控件的顶部悬浮。但是实际应用场景中, * 有可能需要悬浮的控件里面的内容是比较多的,如果通过显示隐藏的方式来实现的话, * 操作控件里的内容时,需要重复定义两套变量,对控件里的内容进行修改时也是要操作再次,非常麻烦。 本文的方法是通过addView和removeView来实现的
当外面嵌套一层ScrollView后,就能做上下或左右滑动,但能滑动多少系统不知道, * 这时就需要你给计算出一个滑动区域给ScrollView。
知识点:
1、当ScrollView垂直滚动视图中嵌套ListView时,ListView必须重写onMeasure方法,返回高度和大小,否则,只会显示一行布局!!!
2、滑动事件会有冲突:重写onInterceptTouchEvent方法(或者其他事件的方法),根据情况获得事件!
首先继承ScrollView类:
public class HoveringScrollview extends ScrollView {
private OnScrollListener onScrollListener;
/**
* 主要是用在用户手指离开本view,本view还在继续滑动,我们用来保存Y的距离,然后做比较
*/
private int lastScrollY;
public HoveringScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
/**
* 设置滚动接口
*
* @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 = HoveringScrollview.this.getScrollY();
// 此时的距离和记录下的距离不相等,在隔6毫秒给handler发送消息?
if (lastScrollY != scrollY) {
lastScrollY = scrollY;
handler.sendMessageDelayed(handler.obtainMessage(), 6);
}
if (onScrollListener != null) {
onScrollListener.onScroll(scrollY);
}
};
};
/**
* 重写onTouchEvent, 当用户的手在HoveringScrollview上面的时候,
* 直接将HoveringScrollview滑动的Y方向距离回调给onScroll方法中,当用户抬起手的时候,
* HoveringScrollview可能还在滑动,所以当用户抬起手我们隔6毫秒给handler发送消息,在handler处理
* HoveringScrollview滑动的距离
*/
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 {
/**
* 回调方法, 返回本view滑动的Y(上下)方向距离
*/
public void onScroll(int scrollY);
}
}
重要方法:
//获得组件的大小(Fragment中)
ViewTreeObserver vto=rlayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
searchLayoutTop=rlayout.getHeight();
}
}); @Override//当hasFocus == true,表示加载完成 Activity中才有该方法
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
searchLayoutTop = rlayout.getBottom();// 获取searchLayout的顶部位置
}
}
Fragment中的JAVA代码:
public class Item_Fragment extends Fragment implements View.OnClickListener, HoveringScrollview.OnScrollListener {
private HoveringScrollview hoveringScrollview;
private int searchLayoutTop;
ViewTop viewtop;
LinearLayout hoveringLayout;
LinearLayout search01, search02;
RelativeLayout rlayout;
RadioGroup radioGroup;
FrameLayout layout;
private ItemZI_Fragment1 fragment1;
private ItemZI_Fragment2 fragment2;
private ItemZI_Fragment3 fragment3,fragment4;
private Bundle bundle;
private Fragment currentFragment;//记录当前显示的碎片对象
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.item_fragment, container, false);
initView(view);
return view;
}
private void initView(View view) {
view.findViewById(R.id.item_msg).setOnClickListener(this);
view.findViewById(R.id.item_camera).setOnClickListener(this);
//悬浮条线性布局(固定大小的布局)[首先嵌套在2号布局里面]
hoveringLayout = (LinearLayout) view.findViewById(R.id.hoveringLayout);
hoveringScrollview = (HoveringScrollview) view.findViewById(R.id.hoveringScrollview);//滚动视图
search01 = (LinearLayout) view.findViewById(R.id.search01);//最下面的3号布局
search02 = (LinearLayout) view.findViewById(R.id.search02);//2号布局
rlayout = (RelativeLayout) view.findViewById(R.id.rlayout);//1号布局(顶部的内容)
layout= (FrameLayout) view.findViewById(R.id.layout);
radioGroup= (RadioGroup) view.findViewById(R.id.item_list_group);
viewtop= (ViewTop) view.findViewById(R.id.viewtop);
viewtop.setOnLienter(new ViewTop.OnListeren() {
@Override
public String[] getURL() {
return URLClass.ItemTops;
}
});
viewtop.setData(true);
hoveringScrollview.setOnScrollListener(this);// set Listener 设置监听
for (int i = 0; i <radioGroup.getChildCount() ; i++) {
//遍历单选组里面的控件,设置点击事件
((RadioButton)radioGroup.getChildAt(i)).setOnClickListener(this);
}
//获取碎片管理器对象, //开启事物,获得操作碎片的对象
FragmentTransaction transaction =getActivity().getSupportFragmentManager().beginTransaction();
fragment1 = new ItemZI_Fragment1();
bundle = new Bundle();
bundle.putString("url",URLClass.ItemURL1);
fragment1.setArguments(bundle);
currentFragment = fragment1;//记录当前的碎片
transaction.add(R.id.layout, fragment1);//添加帧布局和碎片对象
transaction.commit();//提交事物
//获得组件的大小(Fragment中)
ViewTreeObserver vto=rlayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
searchLayoutTop=rlayout.getHeight();
}
});
}
/*
@Override//当hasFocus == true,表示加载完成 Activity中才有该方法
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
searchLayoutTop = rlayout.getBottom();// 获取searchLayout的顶部位置
}
}
*/
@Override//实现的滚动方法
public void onScroll(int scrollY) {
// TODO Auto-generated method stub
if (scrollY >= searchLayoutTop) {
if (hoveringLayout.getParent() != search01) {
search02.removeView(hoveringLayout); //2号布局删除 悬浮体布局
search01.addView(hoveringLayout); //3号底层布局添加 悬浮体布局
}
} else {
if (hoveringLayout.getParent() != search02) {
search01.removeView(hoveringLayout); //3号底层布局删除 悬浮体布局
search02.addView(hoveringLayout); //2号布局添加 悬浮体布局
}
}
}
private int counnt;
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.item_list_b1:
counnt=0;
showFragment(1);
break;
case R.id.item_list_b2:
counnt=1;
showFragment(2);
break;
case R.id.item_list_b3:
counnt=2;
showFragment(3);
break;
case R.id.item_list_b4:
counnt=3;
showFragment(4);
break;
}
for (int i = 0; i <radioGroup.getChildCount() ; i++) {
RadioButton button= (RadioButton) radioGroup.getChildAt(i);
if(i==counnt){
button.setTextColor(getResources().getColor(R.color.main_text_yes));
continue;
}
button.setTextColor(getResources().getColor(R.color.main_text_no));
}
}
//显示碎片对象,隐藏当前的碎片对象
private void showFragment(int index) {
//碎片操作对象,不能定义全局的,负责秒报错
FragmentTransaction transaction =getActivity().getSupportFragmentManager().beginTransaction();
if (index == 1) {//热门碎片
if (fragment1 == null) {
fragment1 = new ItemZI_Fragment1();
bundle = new Bundle();
bundle.putString("url",URLClass.ItemURL1);
fragment1.setArguments(bundle);
}
if (fragment1.isAdded()) {//如果碎片对象存在
transaction.show(fragment1);//显示该碎片
transaction.hide(currentFragment);//隐藏当前碎片(前一个)
} else {//如果碎片对象不存在
transaction.add(R.id.layout, fragment1);//添加碎片
transaction.hide(currentFragment);//隐藏当前的碎片
}
transaction.commit();//提交事件
currentFragment = fragment1;//记录当前显示的碎片
} else if (index == 2) {//关注碎片
if (fragment2 == null) {
fragment2 = new ItemZI_Fragment2();
bundle = new Bundle();
bundle.putString("url",URLClass.ItemURL2);
fragment2.setArguments(bundle);
}
if (fragment2.isAdded()) {//如果碎片对象存在
transaction.show(fragment2);//显示该碎片
transaction.hide(currentFragment);//隐藏当前碎片(前一个)
} else {//如果碎片对象不存在
transaction.add(R.id.layout, fragment2);//添加碎片
transaction.hide(currentFragment);//隐藏当前的碎片
}
transaction.commit();//提交事件
currentFragment = fragment2;//记录当前显示的碎片
} else if (index == 3) {//红人碎片
if (fragment3 == null) {
fragment3 = new ItemZI_Fragment3();
bundle = new Bundle();
bundle.putString("url",URLClass.ItemURL3);
fragment3.setArguments(bundle);
}
if (fragment3.isAdded()) {//如果碎片对象存在
transaction.show(fragment3);//显示该碎片
transaction.hide(currentFragment);//隐藏当前碎片(前一个)
} else {//如果碎片对象不存在
transaction.add(R.id.layout, fragment3);//添加碎片
transaction.hide(currentFragment);//隐藏当前的碎片
}
transaction.commit();//提交事件
currentFragment = fragment3;//记录当前显示的碎片
} else if (index == 4) {//线下店碎片
if (fragment4 == null) {
fragment4 = new ItemZI_Fragment3();
bundle = new Bundle();
bundle.putString("url",URLClass.ItemURL4);
fragment4.setArguments(bundle);
}
if (fragment4.isAdded()) {//如果碎片对象存在
transaction.show(fragment4);//显示该碎片
transaction.hide(currentFragment);//隐藏当前碎片(前一个)
} else {//如果碎片对象不存在
transaction.add(R.id.layout, fragment4);//添加碎片
transaction.hide(currentFragment);//隐藏当前的碎片
}
transaction.commit();//提交事件
currentFragment = fragment4;//记录当前显示的碎片
}
}
}
XML布局: 顶部布局必须为相对布局,否则不会悬浮组件,会覆盖
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<!-- 社区的碎片的布局,相对布局才有效果-->
<android.support.v7.widget.Toolbar
android:id="@+id/item_toolbar"
android:layout_width="match_parent"
android:layout_height="50dp">
<RelativeLayout
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="100dp"
android:gravity="center"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:textSize="20sp"
android:textColor="#181515"
android:text="社区"
/>
<ImageView
android:id="@+id/item_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@mipmap/button_head_massage"/>
<ImageView
android:id="@+id/item_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:layout_toLeftOf="@id/item_msg"
android:layout_centerVertical="true"
android:background="@mipmap/button_head_camera"/>
</RelativeLayout>
</android.support.v7.widget.Toolbar>
<com.android.starapp.view.HoveringScrollview
android:id="@+id/hoveringScrollview"
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">
<com.android.starapp.view.ViewTop
android:id="@+id/viewtop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
<!-- 这个悬浮条必须是固定高度 -->
<LinearLayout
android:id="@+id/search02"
android:layout_width="match_parent"
android:layout_height="70dp">
<LinearLayout
android:id="@+id/hoveringLayout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#fff"
>
<RadioGroup
android:id="@+id/item_list_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="4">
<RadioButton
android:id="@+id/item_list_b1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="@null"
android:checked="true"
android:drawableBottom="@drawable/match_toolbar_main"
android:gravity="center"
android:text="热门"
android:textColor="@color/main_text_yes" />
<RadioButton
android:id="@+id/item_list_b2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="@null"
android:drawableBottom="@drawable/match_toolbar_main"
android:gravity="center"
android:text="关注"
android:textColor="@color/main_text_no" />
<RadioButton
android:id="@+id/item_list_b3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="@null"
android:drawableBottom="@drawable/match_toolbar_main"
android:gravity="center"
android:text="红人"
android:textColor="@color/main_text_no" />
<RadioButton
android:id="@+id/item_list_b4"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="@null"
android:drawableBottom="@drawable/match_toolbar_main"
android:gravity="center"
android:text="线下店"
android:textColor="@color/main_text_no" />
</RadioGroup>
</LinearLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</com.android.starapp.view.HoveringScrollview>
<LinearLayout
android:id="@+id/search01"
android:layout_width="match_parent"
android:layout_height="70dp"
android:orientation="vertical"></LinearLayout>
</RelativeLayout>标签:
原文地址:http://blog.csdn.net/qq_34997963/article/details/51933055