您的位置:首页 > 移动开发 > Android开发

使用HorizontalScrollView实现瑞士军刀界面

2014-11-17 11:22 295 查看
iOS及Android上的瑞士军刀界面很是新颖,也很便捷。很多应用采用了该设计,例如QQ,凤凰新闻客户端等。今天介绍一下通过自定义HorizontalScrollView类的方法实现瑞士军刀界面。

★依赖jar包

NineOldAndroids.jar

 

★思路:

●使用HorizontalScrollView布局,左侧为Menu,右侧为Content;

自定义HorizontalScrollView,使之监听Action_UP事件,进行Menu的显示和隐藏;

 

●menu隐藏在抽屉正下方

属性动画:改变拖动时,

调用动画时机:ACTION_MOVE==>覆写View类的onScrollChanged()方法

 

●菜单及内容区域的缩放和透明度变化

拖动时 scale:1.0-0

menu透明度变化:0.7-1.0

menu缩放变化:0.7-1.0

content缩放变化:1.0-0.7【注意默认缩放中心会影响实际效果,需要设置缩放中心】

 

★效果图

★核心代码实现

JAVA中自定义HorizontalScrollView类:SlidingMenu

------------------------------------------------------------------
public class SlidingMenu extends HorizontalScrollView{
private LinearLayout mWrapper;
private ViewGroup mMenu;
private ViewGroup mContent;
private int menuWidth;
private int slidingMenuPadding;
private int screenWidth;
private boolean once;
private boolean isOpen;
public SlidingMenu(Context context, AttributeSet attr) {
super(context, attr);
DisplayMetrics dm = new DisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;
slidingMenuPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80,
context.getResources().getDisplayMetrics());
}
/**
* 初始化Menu的位置
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.e("SLIDING","onLayout()");
//if (!changed){
Log.e("SLIDING","onLayout() !changed");
this.scrollTo(menuWidth, 0);
//}
super.onLayout(changed, l, t, r, b);
}
/**
* 设置HorizontalScrollView自己的宽度和高度及子View的宽度高度
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.e("SLIDING","onMeasure()");
if (!once){
mWrapper = (LinearLayout) getChildAt(0);
mMenu = (ViewGroup) mWrapper.getChildAt(0);
mContent = (ViewGroup) mWrapper.getChildAt(1);
menuWidth = mMenu.getLayoutParams().width = screenWidth - slidingMenuPadding;
mContent.getLayoutParams().width = screenWidth;
once = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 监听触摸事件,并在手指提起时触发menu的显示或隐藏
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.e("SLIDING","onTouchEvent()");
int action = ev.getAction();
switch (action){
case MotionEvent.ACTION_UP:
Log.e("SLIDING","onMeasure() ACTION_UP");
// scrollX是横向偏移的X轴坐标,随着手的右向滑动,该数值在变小
int scrollX = getScrollX();
if (scrollX >= menuWidth/2){
// 隐藏menu
Log.e("SLIDING","onMeasure() ACTION_UP menuWidth");
this.smoothScrollTo(menuWidth, 0);
isOpen = false;
} else {
// 显示menu
Log.e("SLIDING","onMeasure() ACTION_UP 0");
this.smoothScrollTo(0,0);
isOpen = true;
}
return true;
}
return super.onTouchEvent(ev);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
// 调用属性动画,设置TranslationX,需要使用第三方
4000
jar包
// 定义scroll数值的变化域 scale:1-0
float scale = l * 1.0f/menuWidth;
// 定义content缩放域:1.0-0.7
float rightScale = 0.7f + scale * 0.3f;
// 定义Menu的缩放域 0.7-1.0
float leftScale = 1.0f - scale * 0.3f;
// 设置menu的透明度变化域 0.7-1.0
float leftAlpha = 1.0f - scale * 0.3f;
// menu跟随手指移动(0.5f为更改menu显示时的位置)
ViewHelper.setTranslationX(mMenu, l * 0.5f);
// 对menu进行缩放和透明度变化指定
ViewHelper.setScaleX(mMenu, leftScale);
ViewHelper.setScaleY(mMenu, leftScale);
ViewHelper.setAlpha(mMenu, leftAlpha);
// 对content进行横纵缩放
// 设置content缩放中心为屏幕左侧中心点
ViewHelper.setPivotX(mContent, 0);
ViewHelper.setPivotY(mContent, mContent.getHeight()/2);
ViewHelper.setScaleX(mContent, rightScale);
ViewHelper.setScaleY(mContent, rightScale);
}
public void trigger(){
if (isOpen){
closeMenu();
isOpen = false;
} else {
openMenu();
isOpen = true;
}
}
private void openMenu(){
if (isOpen) return;
this.smoothScrollTo(0,0);
}
private void closeMenu(){
if (!isOpen) return;
this.smoothScrollTo(menuWidth, 0);
}
}
★参考布局

主界面:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/leaf" >
<!--android:scrollbars="none" 去除滚动条 -->
<com.example.dialogtest.SlidingMenu
android:id="@+id/menu_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" >
<include layout="@layout/sliding_menu" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/apple" >
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/title_bar_menu"
android:onClick="showMenu" />
</LinearLayout>
</LinearLayout>
</com.example.dialogtest.SlidingMenu>
</RelativeLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 界面 java 设计