Android滑动ScrollView时使导航栏停留的效果(仿ios的tableview分区)
来源:互联网 发布:志鸿优化系列丛书 编辑:程序博客网 时间:2024/06/06 19:37
首先,我们来看下效果图,如下:
让我们来分析一下这个图,这是一个scrollview,有4个条目,当我们向上滑动的时候,如果条目2滑到顶端,会把
条目1顶上去,然后条目2停留,等待条目3上来,之后条目3会把条目2顶上去,然后停留,后面同理。
那么,这个动态的怎么来实现呢?停留的导航栏是什么呢?
其实,导航栏是一个浮在scrollView上面的一个textView。当条目2滚动到条目1下面的时候,让textview动态的随
着scrollview的滚动而滚动直至条目1滚出屏幕。当条目2滚动到条目1的位置的时候让textView显示在条目1 的位置,
当scrollview继续滚动的时候textview不动,给人一种条目2停留的感觉。以下同理。
好,大概的原理我们已经大致的清楚了,那就开始来看一下布局吧!
<span style="font-size:18px;"><span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.peiwc.iostableview.MyScrollView android:id="@+id/scv" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/title0" android:layout_width="match_parent" android:layout_height="55dp" android:background="#ffF19EDB" android:gravity="center" android:textStyle="bold" android:text="条目1" /> <TextView android:layout_width="match_parent" android:layout_height="300dp" android:adjustViewBounds="true" android:gravity="center" android:scaleType="fitCenter" android:text="text1" android:textSize="26sp" /> <TextView android:id="@+id/title1" android:layout_width="match_parent" android:layout_height="55dp" android:background="@color/colorRed" android:gravity="center" android:text="条目2" android:textStyle="bold" android:textSize="22sp" android:textColor="@android:color/white"/> <TextView android:layout_width="match_parent" android:layout_height="300dp" android:adjustViewBounds="true" android:gravity="center" android:scaleType="fitCenter" android:text="text2" android:textSize="26sp" /> <TextView android:id="@+id/img" android:layout_width="match_parent" android:layout_height="300dp" android:adjustViewBounds="true" android:gravity="center" android:scaleType="fitCenter" android:text="text3" android:textSize="26sp" /> <TextView android:id="@+id/title2" android:layout_width="match_parent" android:layout_height="55dp" android:background="@color/colorYel" android:gravity="center" android:text="条目3" android:textSize="22sp" android:textColor="@android:color/white" android:textStyle="bold"/> <TextView android:id="@+id/iv1" android:layout_width="match_parent" android:layout_height="300dp" android:adjustViewBounds="true" android:gravity="center" android:scaleType="fitCenter" android:text="text4" android:textSize="26sp" /> <TextView android:id="@+id/title3" android:layout_width="match_parent" android:layout_height="55dp" android:background="@color/colorBlue" android:gravity="center" android:text="条目4" android:textSize="22sp" android:textColor="@android:color/white" android:textStyle="bold"/> <TextView android:layout_width="match_parent" android:layout_height="300dp" android:adjustViewBounds="true" android:gravity="center" android:scaleType="fitCenter" android:text="text5" android:textSize="26sp" /> <TextView android:layout_width="match_parent" android:layout_height="300dp" android:adjustViewBounds="true" android:gravity="center" android:scaleType="fitCenter" android:text="text6" android:textSize="26sp" /> <TextView android:layout_width="match_parent" android:layout_height="300dp" android:adjustViewBounds="true" android:gravity="center" android:scaleType="fitCenter" android:text="text7" android:textSize="26sp" /> </LinearLayout> </com.example.peiwc.iostableview.MyScrollView> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="55dp" android:background="@color/colorZi" android:gravity="center" android:textSize="22sp" android:textColor="@android:color/white" android:textStyle="bold" android:text="条目1" /></RelativeLayout></span></span>
这个布局整体是个Relativelayout,里面在scrollview上面有一个textview title,我们给4个条目都设置了id,分别是title0,title1,title2,title3.可以看到scrollview被重写了
为什么要重写scrollview呢?
因为我们要对scrollview进行监听,获得scrollview滑动的距离,从而控制title的位移。可惜sdk并没哟响应的方法,但是scrollview中倒是提供了一个方法
<pre name="code" class="java"><span style="font-size:18px;"> @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (scrollViewListener != null) { scrollViewListener.onScrollChanged( x, y, oldx, oldy); } }</span>
显然这个方法是不能被外界调用的,因此我们要把它暴露出去,方便使用。
下面帖上程序代码我们来具体看下ScrollView:
<pre name="code" class="java"><span style="font-size:18px;">public class MyScrollView extends ScrollView { private ScrollViewListener scrollViewListener = null; public MyScrollView(Context context) { super(context); } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public interface ScrollViewListener { void onScrollChanged( int x, int y, int oldx, int oldy); } public void setScrollViewListener(ScrollViewListener scrollViewListener) { this.scrollViewListener = scrollViewListener; }// onScrollChanged里面有4个参数,l代表滑动后当前ScrollView可视界面的左上角在整个ScrollView的X轴中的位置,oldi也就是滑动前的X轴位置了。// 同理,t也是当前可视界面的左上角在整个ScrollView的Y轴上的位置,oldt也就是移动前的Y轴位置了。 @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (scrollViewListener != null) { scrollViewListener.onScrollChanged( x, y, oldx, oldy); } }}</span>
接下来,就是我们华丽丽的Activity闪亮登场啦!先把整篇帖上去,然后我再仔细讲。
<pre name="code" class="java"><span style="font-size:18px;">public class MainActivity extends Activity implements MyScrollView.ScrollViewListener{ private TextView title0,title1,title2,title3,title; private long topDistance0,topDistance1,topDistance2,topDistance3,height; private MyScrollView scrollView; private int distance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); title0=(TextView)findViewById(R.id.title0); title1=(TextView)findViewById(R.id.title1); title2=(TextView)findViewById(R.id.title2); title3=(TextView)findViewById(R.id.title3); title=(TextView)findViewById(R.id.title); scrollView=(MyScrollView)findViewById(R.id.scv); scrollView.setScrollViewListener(this); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if(hasFocus){ topDistance0 = title0.getTop(); topDistance1 = title1.getTop(); topDistance2 = title2.getTop(); topDistance3 = title3.getTop();//按钮左上角相对于父view(LinerLayout)的y坐标 height = title.getMeasuredHeight(); Log.i("","=topDistance0="+topDistance0); Log.i("","=topDistance1="+topDistance1); Log.i("","=topDistance2="+topDistance2); Log.i("","=topDistance3="+topDistance3); Log.i("","=topDistance3="+topDistance3); Log.i("","=height="+height); } } @Override public void onScrollChanged(int x, int y, int oldx, int oldy) { Log.i("","=topDistance=distance="+"x="+x+";y="+y+";oldx="+oldx+";oldy"+oldy); distance=y; distancePlace(topDistance0,topDistance1); distancePlaceLayout(topDistance1,topDistance0); distancePlace(topDistance1,topDistance2); distancePlaceLayout(topDistance2,topDistance1); distancePlace(topDistance2,topDistance3); distancePlaceLayout(topDistance3,topDistance2); if (distance > topDistance3) { title.layout(0,0,title.getRight(),(int)height); showText(topDistance3); } } private void distancePlaceLayout(long topDistance1,long topDistance0){ if(distance>topDistance1-height && distance<topDistance1 ){ title.layout(0,(int)(topDistance1-distance-height),title.getRight(),(int)(topDistance1-distance)); showText(topDistance0); } } private void distancePlace(long topDistance0,long topDistance1){ if(distance >= topDistance0&& distance<topDistance1-height){ title.layout(0,0,title.getRight(),(int)height); showText(topDistance0); } } private void showText(long topDistance){ if(topDistance==topDistance0){ title.setText("条目1"); title.setBackground(getResources().getDrawable(R.color.colorZi)); } if(topDistance==topDistance1){ title.setText("条目2"); title.setBackground(getResources().getDrawable(R.color.colorRed)); } if(topDistance==topDistance2){ title.setText("条目3"); title.setBackground(getResources().getDrawable(R.color.colorYel)); } if(topDistance==topDistance3){ title.setText("条目4"); title.setBackground(getResources().getDrawable(R.color.colorBlue)); } }}</span>
在onWindowFocusChanged(boolean hasFocus)中,获取了4个条目的getTop值,即条目到scrollview顶端的距离。注意:getTop是控件左上角相对于父布局的y坐标。这个布局中所有条目的父布局都是scrollview,所以我们这里可以直接使用。我们看下打印的结果:
来看下onScrollChange方法:
当条目2到达条目1低端的时候,滑动的距离就应该是topDistance1-height,即title1.getTop-height,height是条目的高度。那么当条目2还没有到达条目1 低端的时候,如图,我们做了如下的判断:
<pre name="code" class="java"><span style="font-size:18px;">if(distance >= topDistance0 && distance<topDistance1-height){ title.layout(0,0,title.getRight(),(int)height); showText(topDistance0); }</span>
当条目2到达条目1低端和条目1顶端之间的位置,即条目2往上推动条目1的时候
滑动的距离就应该是topDistance1-height和即topDistance1之间,我们做了如下的判断:
<pre name="code" class="java"><span style="font-size:18px;">if(distance>topDistance1-height && distance<topDistance1 ){ title.layout(0,(int)(topDistance1-distance-height),title.getRight(),(int)(topDistance1-distance)); showText(topDistance0); }</span>
此时title是动态的,我们根据滑动的距离实时给title定个位。
剩下的条目依次类推。
把这两个判断做下封装,传入不同的距离值就可以啦!
OK,demo完成!
源码:http://download.csdn.net/detail/aa_chao/9635014
- Android滑动ScrollView时使导航栏停留的效果(仿ios的tableview分区)
- android-仿美丽说有滑动效果的导航栏
- android-仿美丽说有滑动效果的导航栏
- android-仿美丽说有滑动效果的导航栏
- android-仿美丽说有滑动效果的导航栏
- android-仿美丽说有滑动效果的导航栏
- Android 自带阻尼效果的ScrollView,仿ios效果
- iOS滑动tableView来改变导航栏的颜色
- iOS滑动tableView来改变导航栏的颜色
- iOS滑动tableView来改变导航栏的颜色
- android 仿ios带弹簧效果的ScrollView
- android仿IOS,滑动隐藏底部ScrollView
- 仿网易的滑动门导航效果代码(DIV+CSS)
- android-仿美丽说按下效果的顶部导航栏
- 学习笔记之——自定义带滑动距离监控和仿iOS回弹效果的ScrollView
- Android仿IOS回弹效果 ScrollView回弹
- Android实现导航栏的左右滑动效果
- 【Android】仿IOS的滑动按钮
- android之merge布局
- java中的匿名内部类总结
- 数据结构 学习笔记(三):线性结构:堆栈,队列,表达式求值,多项式加法运算
- [BZOJ2599][IOI2011]Race(点分治)
- 如何分析解决Android ANR
- Android滑动ScrollView时使导航栏停留的效果(仿ios的tableview分区)
- c++ 模板(Templates)
- 博客地址更新www.zt-zhaoteng.cn
- Proteus网络标号批量编号
- 关于责任心
- 热血群英传隐私政策
- Jmeter 脚本录制
- iOS10适配之通知(UserNotification)
- UVA 1395 Slim Span(MST)