編輯:關於Android編程
菜單分左右兩側,整體可以滑動,效果如下


widthMeasureSpec:期望值
組成: 32位的010101010101011010101組成 頭2位:代表的是模式scrollTo:
移動的是手機的屏幕 標准移動scrollBy:
移動的是手機的屏幕 增量移動Scroller: 用來模擬數據變化
computeScroll()ViewDragHelper:
用來分析touch事件的工具類使用步驟
獲取實例
ViewDragHelper helper =ViewDragHelper.create(ViewGroup, CallBack);
touch分析和監聽
@Override
public boolean onTouchEvent(MotionEvent event) {
mHelper.processTouchEvent(event);
return true;
}
實現自己的callBack
touch:
down左菜單(left.xml)
右邊主界面(content.xml)
drawable目錄下tab_bg.xml選擇器
styles.xml
SlidingMenu.java
package com.cdw.slidingmenu;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
/**
* Created by dongwei on 2016/8/2.
*/
public class SlidingMenu extends ViewGroup {
private View mLeftView;
private View mContentView;
private int mLeftWidth;
private float mDownX;
private float mDownY;
private Scroller mScroller;
private boolean isLeftShow = false;
public SlidingMenu(Context context) {
this(context, null);
}
public SlidingMenu(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);
}
@Override
protected void onFinishInflate() {
//xml加載完成時
mLeftView = getChildAt(0);
mContentView = getChildAt(1);
LayoutParams params = mLeftView.getLayoutParams();
mLeftWidth = params.width;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//測量孩子
int leftWidthMeasureSpec = MeasureSpec.makeMeasureSpec(mLeftWidth, MeasureSpec.EXACTLY);
mLeftView.measure(leftWidthMeasureSpec, heightMeasureSpec);
mContentView.measure(widthMeasureSpec, heightMeasureSpec);
//設置自己的寬度和高度
int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(measuredWidth, measuredHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int width = mLeftView.getMeasuredWidth();
int height = mLeftView.getMeasuredHeight();
//給左側布局
int lvLeft = -width;
int lvTop = 0;
int lvRight = 0;
int lvBottom = height;
mLeftView.layout(lvLeft, lvTop, lvRight, lvBottom);
//給右側布局
int cLeft = 0;
int cTop = 0;
int cRight = mContentView.getMeasuredWidth();
int cBottom = mContentView.getMeasuredHeight();
mContentView.layout(cLeft, cTop, cRight, cBottom);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
mDownX = ev.getX();
mDownY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float moveX = ev.getX();
float moveY = ev.getY();
if (Math.abs(moveX - mDownX) > Math.abs(moveY - mDownY)){
//水平方向移動
return true;
}
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
mDownX = event.getX();
mDownY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float moveX = event.getX();
float moveY = event.getY();
int diffX = (int) (mDownX - moveX + 0.5f);
int scrollX = getScrollX() + diffX;
if (scrollX < 0 && scrollX < -mLeftView.getMeasuredWidth()){
scrollTo(-mLeftView.getMeasuredWidth(), 0);
}else if (scrollX > 0){
scrollTo(0, 0);
}else {
scrollBy(diffX, 0);
}
mDownX = moveX;
mDownY = moveY;
break;
case MotionEvent.ACTION_UP:
//判斷是打開還是關閉
int width = mLeftView.getMeasuredWidth();
int currentX = getScrollX();
float middle = -width / 2f;
switchMenu(currentX <= middle);
break;
default:
break;
}
return true;
}
private void switchMenu(boolean showLeft) {
isLeftShow = showLeft;
int width = mLeftView.getMeasuredWidth();
int currentX = getScrollX();
if (!showLeft){
//scrollTo(0, 0);
int startX = currentX;
int startY = 0;
int endX = 0;
int endY = 0;
int dx = endX - startX;
int dy = endY - startY;
int duration = Math.abs(dx) * 10;
if (duration >= 600){
duration = 600;
}
//模擬數據變化
mScroller.startScroll(startX, startY, dx, dy, duration);
}else {
//scrollTo(-width, 0);
int startX = currentX;
int startY = 0;
int endX = -width;
int endY = 0;
int dx = endX - startX;
int dy = endY - startY;
int duration = Math.abs(dx) * 10;
if (duration >= 600){
duration = 600;
}
mScroller.startScroll(startX, startY, dx, dy, duration);
}
invalidate();
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()){
//更新位置
scrollTo(mScroller.getCurrX(), 0);
invalidate();
}
}
public void toggle(){
switchMenu(!isLeftShow);
}
}
mainActivity.java
package com.cdw.slidingmenu;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private SlidingMenu menu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
menu = (SlidingMenu) findViewById(R.id.sm);
}
public void clickTab(View view){
String text = ((TextView)view).getText().toString();
Toast.makeText(this, "點擊了" + text, Toast.LENGTH_SHORT).show();
menu.toggle();
}
public void clickBack(View view){
menu.toggle();
}
}
項目鏈接:Android/tree/ec78b9b3d2d3bb22b51b0784d26dca18960ab01a/slidingmenu">https://github.com/ChenDongWei/Android/tree/ec78b9b3d2d3bb22b51b0784d26dca18960ab01a/slidingmenu
Android動畫機制與使用技巧(五)——Android 5.X SVG 矢量動畫機制
Google在Android 5.X 中增加了對SVG 矢量圖形的支持,這對於創建新的高效率動畫具有非常重大的意義。那首先了解SVG的含義。可伸縮矢量圖形(Scalabl
Android實現滑動刪除操作(PopupWindow)
參考Android仿騰訊QQ實現滑動刪除這篇文章進行學習,文章實現的功能是:在ListView的Item上從右向左滑時,出現刪除按鈕,點擊刪除按鈕把Item刪除,效果看過
Android模擬器2.0初探
我相信每一個安卓開發者都會同意2015年安卓開發者大會上宣布的最大事情就是 Android Studio 2.0和安卓模擬器2.0,其中安卓模擬器2.0宣稱運行和部署應用
Android Fragment 嵌套使用報錯
在新的SDK每次創建activity時,會自動生成 public static class PlaceholderFragment extends Fragment f