Android开发进阶系列(四) 左移拉出Menu菜单界面布局
来源:互联网 发布:咦是什么意思网络用语 编辑:程序博客网 时间:2024/04/28 06:57
08、09年的时候,我们在Symbian平台上开发了一款LBS的交友软件,对于Symbian平台的UI界面开发是颇为诟病的。Android的出现让人眼前一亮,当时还只是几个UI界面的Demo效果就已经让人大开眼界了。随着Android的爆发式增长,Android上开发的UI界面一个比一个炫。下面要介绍的Menu拉出式界面布局是在2013年做的一个APP,这种界面布局的特点是整洁有序,中规中矩。
APK下载地址:http://apk.hiapk.com/appinfo/com.lingling.guitachordplayer
链接里有截图,这里就不占用篇幅了。
Layout布局文件
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/layout_right" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="50dp" android:orientation="vertical" > <AbsoluteLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/grey21" android:padding="6dp" > <TextView android:layout_width="50dp" android:layout_height="wrap_content" android:text="@string/settings" android:textColor="@android:color/background_light" android:textSize="16sp" /> </AbsoluteLayout> <com.lingling.guitachordplayer.MyLinearLayout android:id="@+id/mylaout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" > <ListView android:id="@+id/lv_set" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ListView> </com.lingling.guitachordplayer.MyLinearLayout> </LinearLayout> <LinearLayout android:id="@+id/layout_left" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/white" android:orientation="vertical" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/side_nav_bg" > <ImageView android:id="@+id/iv_set" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:clickable="true" android:src="@drawable/menuimage" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/app_name" android:textColor="@android:color/background_light" android:textSize="20sp" /> <ImageView android:id="@+id/iv_share" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:clickable="true" android:src="@drawable/share_btn" /> </RelativeLayout> <com.lingling.guitachordplayer.MyLinearLayout android:id="@+id/favoritelaout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" > <ListView android:id="@+id/lv_favorite" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ListView> </com.lingling.guitachordplayer.MyLinearLayout> </LinearLayout></RelativeLayout>
这里其实把左右两个Layout都定义了。
View的初始化
/*** * 初始化view */ void InitView() { layout_left = (LinearLayout) findViewById(R.id.layout_left); layout_right = (LinearLayout) findViewById(R.id.layout_right); iv_set = (ImageView) findViewById(R.id.iv_set); mylaout = (MyLinearLayout) findViewById(R.id.mylaout); favorlaout = (MyLinearLayout) findViewById(R.id.favoritelaout); lv_set.setAdapter(new ArrayAdapter<String>(this, R.layout.item, R.id.tv_item, title)); lv_favor = (ListView) findViewById(R.id.lv_favorite); favorList = new ArrayList<Map<String, Object>>(); /*** * 实现该接口 */ mylaout.setOnScrollListener(new OnScrollListener() { @Override public void doScroll(float distanceX) { doScrolling(distanceX); } @Override public void doLoosen() { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left .getLayoutParams(); // 缩回去 //if (layoutParams.leftMargin < -window_width / 2) { if (layoutParams.leftMargin == -MAX_WIDTH) { // 点击,并未滑动,无需处理 } else if (layoutParams.leftMargin < -window_width + 100) { // 缩回去 new AsynMove().execute(-SPEED); } else { // 滑动 new AsynMove().execute(SPEED); } } }); //favorlaout favorlaout.setOnScrollListener(new OnScrollListener() { @Override public void doScroll(float distanceX) { doScrolling(distanceX); } @Override public void doLoosen() { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left .getLayoutParams(); // 缩回去 //if (layoutParams.leftMargin < -window_width / 2) { if (layoutParams.leftMargin == 0) { // 点击,并未滑动,无需处理 } else if (layoutParams.leftMargin < -50) { new AsynMove().execute(-SPEED); } else { new AsynMove().execute(SPEED); } } }); // 点击监听 lv_set.setOnItemClickListener(this); lv_favor.setOnItemClickListener(this); layout_right.setOnTouchListener(this); layout_left.setOnTouchListener(this); iv_set.setOnTouchListener(this); mGestureDetector = new GestureDetector(this); // 禁用长按监听 mGestureDetector.setIsLongpressEnabled(false); getMAX_WIDTH(); } /*** * 获取移动距离 移动的距离其实就是layout_left的宽度 */ void getMAX_WIDTH() { ViewTreeObserver viewTreeObserver = layout_left.getViewTreeObserver(); // 获取控件宽度 viewTreeObserver.addOnPreDrawListener(new OnPreDrawListener() { @Override public boolean onPreDraw() { if (!hasMeasured) { window_width = getWindowManager().getDefaultDisplay() .getWidth(); MAX_WIDTH = layout_right.getWidth(); RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left .getLayoutParams(); RelativeLayout.LayoutParams layoutParams_1 = (RelativeLayout.LayoutParams) layout_right .getLayoutParams(); ViewGroup.LayoutParams layoutParams_2 = mylaout .getLayoutParams(); // 注意: 设置layout_left的宽度。防止被在移动的时候控件被挤压 layoutParams.width = window_width; layout_left.setLayoutParams(layoutParams); // 设置layout_right的初始位置. layoutParams_1.leftMargin = window_width; layout_right.setLayoutParams(layoutParams_1); // 注意:设置lv_set的宽度防止被在移动的时候控件被挤压 layoutParams_2.width = MAX_WIDTH; mylaout.setLayoutParams(layoutParams_2); hasMeasured = true; } return true; } }); }
处理手势动作
/*** * listview 正在滑动时执行. */ void doScrolling(float distanceX) { isScrolling = true; mScrollX += distanceX;// distanceX:向左为正,右为负 RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left .getLayoutParams(); RelativeLayout.LayoutParams layoutParams_1 = (RelativeLayout.LayoutParams) layout_right .getLayoutParams(); layoutParams.leftMargin -= mScrollX; layoutParams_1.leftMargin = window_width + layoutParams.leftMargin; if (layoutParams.leftMargin >= 0) { isScrolling = false;// 拖过头了不需要再执行AsynMove了 layoutParams.leftMargin = 0; layoutParams_1.leftMargin = window_width; } else if (layoutParams.leftMargin <= -MAX_WIDTH) { // 拖过头了不需要再执行AsynMove了 isScrolling = false; layoutParams.leftMargin = -MAX_WIDTH; layoutParams_1.leftMargin = window_width - MAX_WIDTH; } layout_left.setLayoutParams(layoutParams); layout_right.setLayoutParams(layoutParams_1); }
处理点击事件
/* * 滑动监听 就是一个点移动到另外一个点. distanceX=后面点x-前面点x,如果大于0,说明后面点在前面点的右边及向右滑动 */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // 执行滑动. doScrolling(distanceX); return false; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left .getLayoutParams(); if (layoutParams.leftMargin < 0) { new AsynMove().execute(SPEED); return false; } else { // Popup window showExitGameAlert(); } } if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left .getLayoutParams(); if (layoutParams.leftMargin < 0) { new AsynMove().execute(SPEED); return false; } else { new AsynMove().execute(-SPEED); return false; } } return super.onKeyDown(keyCode, event); } @Override public boolean onTouch(View v, MotionEvent event) { view = v;// 记录点击的控件 // 松开的时候要判断,如果不到半屏幕位子则缩回去, if (MotionEvent.ACTION_UP == event.getAction() && isScrolling == true) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left .getLayoutParams(); // 缩回去 // 拉动50px就认为是拉动而不是点击 //if (layoutParams.leftMargin < -window_width / 2) { if (layoutParams.leftMargin < -50) { new AsynMove().execute(-SPEED); } else { new AsynMove().execute(SPEED); } } return mGestureDetector.onTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { int position = lv_set.pointToPosition((int) e.getX(), (int) e.getY()); if (position != ListView.INVALID_POSITION) { View child = lv_set.getChildAt(position - lv_set.getFirstVisiblePosition()); if (child != null) child.setPressed(true); } mScrollX = 0; isScrolling = false; // 将之改为true,才会传递给onSingleTapUp,不然事件不会向下传递. return true; } @Override public void onShowPress(MotionEvent e) { } /*** * 点击松开执行 */ @Override public boolean onSingleTapUp(MotionEvent e) { // 点击的不是layout_left if (view != null && view == iv_set) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left .getLayoutParams(); // 左移动 if (layoutParams.leftMargin >= 0) { new AsynMove().execute(-SPEED); lv_set.setSelection(0);// 设置为首位. } else { // 右移动 new AsynMove().execute(SPEED); } } else if (view != null && view == iv_share) { if(!FusionField.isUnlocked) { // 弹出激活对话框 final ActivateCodeDialog.Builder builder2 = new ActivateCodeDialog.Builder(MainActivity.this,FusionField.deviceID); builder2.setPositiveButtonListener(new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { String code = builder2.getCode(); if(code.equals(FusionField.getMD5(FusionField.deviceID))) { FusionField.isUnlocked=true; FusionField.editor.putBoolean("Unlocked", true); FusionField.editor.commit(); Toast toast = Toast.makeText(getApplicationContext(),"激活成功!", Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); dialog.dismiss(); } else { Toast toast = Toast.makeText(getApplicationContext(),"激活失败!", Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); } } }); builder2.create().show(); } else { // 分享 captureScreen(); Intent intent = new Intent(Intent.ACTION_SEND); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setType("image/png"); intent.putExtra(Intent.EXTRA_TITLE,getString(R.string.app_name)); intent.putExtra(Intent.EXTRA_STREAM,Uri.parse(FusionField.sharedFileName)); startActivity(Intent.createChooser(intent, "分享方式")); } } else if (view != null && view == layout_left) { RelativeLayout.LayoutParams layoutParams = (android.widget.RelativeLayout.LayoutParams) layout_left .getLayoutParams(); if (layoutParams.leftMargin < 0) { // 说明layout_left处于移动最左端状态,这个时候如果点击layout_left应该直接所以原有状态.(更人性化) // 右移动 new AsynMove().execute(SPEED); } } return true; }
- * Android开发进阶系列(一) 序言 *
- * Android开发进阶系列(二) Tab页界面布局 *
- * Android开发进阶系列(三) 系统参数的获取和Broadcast *
- * Android开发进阶系列(四) 左移拉出Menu菜单界面布局 *
- * Android开发进阶系列(五) 连接服务器更新APK或下载资源文件 *
- * Android开发进阶系列(六) ListView的基本用法 *
- * Android开发进阶系列(七) 使用数据库 *
- * Android开发进阶系列(八) 界面美化之自定义弹出框 *
- * Android开发进阶系列(九) AChartEngine专题 *
1 0
- Android开发进阶系列(四) 左移拉出Menu菜单界面布局
- Android开发进阶系列(二) Tab页界面布局
- Android界面布局(Layout)和菜单(Menu)
- Android 界面开发之菜单Menu用法
- mars android开发之四:menu菜单
- Android界面编程之Menu(菜单)
- Android笔记(四)Menu菜单
- Android开发之四(十四):常用控件之菜单(Menu)
- Android开发8:menu菜单
- Android菜单(Menu)
- android的布局(Layout)和菜单(Menu)
- android之布局(Layout)和菜单(Menu)
- Python Tkinter界面应用开发-05 拉出
- Android UI开发--Android中五种常用的menu(菜单)
- Android系列之UI组件----Menu菜单
- Android系列之UI组件----Menu菜单
- Android系列之UI组件----Menu菜单
- Android系列之UI组件----Menu菜单
- unicode下的SetWindowTextW------unicode最好不要与C代码一起使用
- 最小生成树的普里姆算法
- 第十二周 项目4-利用遍历思想求解图问题(4)
- myslq backup
- 检查表是否存在
- Android开发进阶系列(四) 左移拉出Menu菜单界面布局
- SharedPreferences数据存储
- 项目4-利用遍历思想求解图问题
- 获取当前日期
- vs2010项目属性配置
- android 注入js的基本使用
- Webx框架指南
- 第四周:项目二——建设单链表算法库
- Jacobian矩阵,Hessian矩阵和牛顿法