一个侧屏滑动操作的实例(仿遇见)之三:代码分析
2012-08-13 10:54
489 查看
一个侧屏滑动操作的实例(仿遇见)之三:代码分析
分类: android UI androidview2012-08-12 22:43 134人阅读 评论(0) 收藏 举报
首先看一下主activity:
[java] view
plaincopy
package grimbo.android.demo.slidingmenu;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
private MyHorizontalScrollView scrollView;
private View leftMenu;
private View rightMenu;
private View tab01;
private Button leftButton;
private Button rightButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = LayoutInflater.from(this);
setContentView(inflater.inflate(R.layout.main, null));
scrollView = (MyHorizontalScrollView) findViewById(R.id.myScrollView);
leftMenu = findViewById(R.id.leftmenu);
rightMenu = findViewById(R.id.rightmenu);
tab01 = inflater.inflate(R.layout.tab01, null);
leftButton = (Button) tab01.findViewById(R.id.leftButton);
rightButton = (Button)tab01.findViewById(R.id.rightButton);
leftButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scrollView.clickLeftButton(leftButton.getMeasuredWidth());
}
});
rightButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scrollView.clickRightButton(rightButton.getMeasuredWidth());
}
});
View leftView = new View(this);//左边透明视图
View rightView = new View(this);//右边透明视图
leftView.setBackgroundColor(Color.TRANSPARENT);
rightView.setBackgroundColor(Color.TRANSPARENT);
final View[] children = new View[] {leftView, tab01,rightView };
//初始化滚动布局
scrollView.initViews(children, new SizeCallbackForMenu(leftButton),leftMenu,rightMenu);
}
}
其中tab01是一个由布局文件tab01.xml定义的view,放置“左边”和“右边”两个按钮
View leftView = new View(this);//左边透明视图
View rightView = new View(this);//右边透明视图
leftView.setBackgroundColor(Color.TRANSPARENT);
rightView.setBackgroundColor(Color.TRANSPARENT);
四句定义两个透明视图,透明视图就是只占用空间,不遮挡放置在其下面的视图
scrollView.initViews把两个透明视图和一个中间的tab视图放入HorizontalScrollView 的LinearLayout里,LinearLayout是横向布局,这样tab移到屏幕可视范围的时候就遮住了底下的leftmenu和rightmenu,当两侧透明视图移入屏幕可视范围的时候,底下的leftmenu或rightmenu就显现出来了,以此实现侧滑效果
然后看一下自定义的滑动类MyHorizontalScrollView
[java] view
plaincopy
package grimbo.android.demo.slidingmenu;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.view.GestureDetector.OnGestureListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.Scroller;
public class MyHorizontalScrollView extends HorizontalScrollView {
private final String tag = "MyHorizontalScrollView";
private MyHorizontalScrollView me;//当前控件
private View leftMenu;//左边菜单
private View rightMenu;//右边菜单
private boolean leftMenuOut = false;//左边菜单状态
private boolean rightMenuOut = false;//左边菜单状态
private final int ENLARGE_WIDTH = 20;//扩展宽度
public MyHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public MyHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MyHorizontalScrollView(Context context) {
super(context);
init(context);
}
void init(Context context) {
// remove the fading as the HSV looks better without it
//setHorizontalFadingEdgeEnabled(true);
//setVerticalFadingEdgeEnabled(true);
me = this;
me.setVisibility(View.INVISIBLE);
}
public void initViews(View[] children, SizeCallback sizeCallback,View leftMenu,View rightMenu) {
this.leftMenu = leftMenu;
this.rightMenu = rightMenu;
ViewGroup parent = (ViewGroup) getChildAt(0);
// Add all the children, but add them invisible so that the layouts are calculated, but you can't see the Views
for (int i = 0; i < children.length; i++) {
children[i].setVisibility(View.INVISIBLE);
parent.addView(children[i]);
}
// Add a layout listener to this HSV
// This listener is responsible for arranging the child views.
OnGlobalLayoutListener listener = new MyOnGlobalLayoutListener(parent, children, sizeCallback);
getViewTreeObserver().addOnGlobalLayoutListener(listener);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Do not allow touch events.
return false;
}
class MyOnGlobalLayoutListener implements OnGlobalLayoutListener {
ViewGroup parent;
View[] children;
int scrollToViewPos = 0;
SizeCallback sizeCallback;
public MyOnGlobalLayoutListener(ViewGroup parent, View[] children, SizeCallback sizeCallback) {
this.parent = parent;
this.children = children;
this.sizeCallback = sizeCallback;
}
@Override
public void onGlobalLayout() {
me.getViewTreeObserver().removeGlobalOnLayoutListener(this);
sizeCallback.onGlobalLayout();
parent.removeViewsInLayout(0, children.length);
final int w = me.getMeasuredWidth();
final int h = me.getMeasuredHeight();
int[] dims = new int[2];
scrollToViewPos = 0;
for (int i = 0; i < children.length; i++) {
sizeCallback.getViewSize(i, w, h, dims);
children[i].setVisibility(View.VISIBLE);
parent.addView(children[i], dims[0], dims[1]);
if (i == 0) {
scrollToViewPos += dims[0];
}
Log.d(tag, children[i]+": w=" + dims[0] + ", h=" + dims[1]);
Log.d(tag, "scrollToViewIdx:"+0+",scrollToViewPos:"+scrollToViewPos);
}
new Handler().post(new Runnable() {
@Override
public void run() {
me.scrollBy(scrollToViewPos,0);
//因为这些控件默认都为隐藏,控件加载完成后,设置成显示
me.setVisibility(View.VISIBLE);
leftMenu.setVisibility(View.VISIBLE);
rightMenu.setVisibility(View.VISIBLE);
}
});
}
}
public void clickLeftButton(int leftButtonWidth){
rightMenu.setVisibility(View.GONE);
leftMenu.setVisibility(View.VISIBLE);
int menuWidth = leftMenu.getMeasuredWidth()-(leftButtonWidth+ENLARGE_WIDTH);
System.out.println("leftmenuWidth:"+menuWidth);
if (!leftMenuOut) {
int left = 0;
me.smoothScrollTo(left, 0);
} else {
int left = menuWidth;
me.smoothScrollTo(left, 0);
}
leftMenuOut = !leftMenuOut;
}
public void clickRightButton(int rightButtonWidth){
<span style="white-space:pre"> </span>leftMenu.setVisibility(View.GONE);
rightMenu.setVisibility(View.VISIBLE);
int menuWidth = rightMenu.getMeasuredWidth() - (rightButtonWidth+ENLARGE_WIDTH);
if (!rightMenuOut) {
int right = menuWidth + me.getMeasuredWidth();
System.out.println("rightmenuWidth:"+right);
me.smoothScrollTo(right, 0);
} else {
int right = menuWidth;
System.out.println("rightmenuWidth:"+right);
me.smoothScrollTo(right, 0);
}
rightMenuOut = !rightMenuOut;
}
@Override
<span style="white-space:pre"> </span>public boolean onTouchEvent(MotionEvent ev) {
return false;
}
public interface SizeCallback {
public void onGlobalLayout();
public void getViewSize(int idx, int w, int h, int[] dims);
}
}
initViews:把传入的view加入第0个viewgroup,也就是xml中配置的LinearLayout中,并把一个MyOnGlobalLayoutListener对象设置为layout变化的观察者,initViews中放入的view只是占了个位置,后面的onGlobalLayout中会重新给这些view分配高和宽并加到LinearLayout中,但是在这之前需要预先放上去以得到某些控件的size(sizeCallback.onGlobalLayout()中),所以需要在这先加一次
onGlobalLayout:作为观察者,会在view的layout发生发生改变时自动调用此方法,由于只需要调用一次,所以方法里第一句就是调用removeGlobalOnLayoutListener,这个方法的主要功能就是把需要加入layout的views按照计算的宽度并加上去,然后调用me.scrollBy(scrollToViewPos,0);使加上去的view偏移,让tab01这个view偏移到屏幕可视范围中
clickLeftButton,clickRightButton:点击左边和右边的按钮时,控制MyHorizontalScrollView自身移动,显示出侧面相应的功能菜单,注意在移动之前,最左侧和最右侧是屏幕外的leftview和rightview,所以:
int left = 0;
me.smoothScrollTo(left, 0);
是把leftview移进来,中间的tab01向右移
完整源码下载地址:
http://download.csdn.net/detail/lamp_zy/4494989
相关文章推荐
- 一个侧屏滑动操作的实例(仿遇见)之三:代码分析
- 一个侧屏滑动操作的实例(仿遇见)之二:布局XML
- 一个侧屏滑动操作的实例(仿遇见)之一:理论基础
- 一个侧屏滑动操作的实例(仿遇见)之二:布局XML
- 一个侧屏滑动操作的实例(仿遇见)之一:理论基础
- 一个线程池实例代码的分析
- Python 文件操作技巧(File operation) 实例代码分析
- php和数据库结合的一个 简单的web实例 代码分析 (php初学者)
- php和数据库结合的一个简单的web实例 代码分析 (php初学者)
- Python 文件操作技巧(File operation) 实例代码分析
- 一个C++开发App的代码实例分析
- php和数据库结合的一个简单的web实例 代码分析 (php初学者)
- c# 流的概念以及一个操作文本文件的实例代码
- php和数据库结合的一个 简单的web实例 代码分析 (php初学者)
- php和数据库结合的一个简单的web实例 代码分析 (php初学者)
- **Android三五行代码结局有滑块,可滑动的TABLE导航栏。类似斗鱼直播的直播页面导航栏,滑块可动态根据栏目宽度适应,无需自定义view** 先来说下思路把,很简单,一个HorizontalS
- opencv中Mat类型操作或转换代码分析
- JavaScript文档碎片操作实例分析
- 一个简单的时间片轮转多道程序内核代码的分析
- php文件操作实例代码