Android實現類似launcher的滑動桌面
這個例子中涉及到了以下幾個知識點:
- 1) attrs.xml文件的使用
- 2) GestureDetector.OnGestureListener監聽手勢
- 3) onLayout()、onMeasure()、onTouchEvent()的使用 </ul>
- 1) 每個桌面就是一個大組件,水平的排列在線性布局文件中,每個桌面適合屏幕一樣大小,所以要拓展LinearLayout,重寫其中的onMeasure()、onLayout()方法
- 2) 由于要實現隨手勢滑動,所以只要實現GestureDetector.OnGestureListener接口中的onDown()、onScroll()方法就可以
- 3) 由于要接收觸屏事件,所以要實現onTouchEvent()
接下來說一下我實現的思路:
接下來我們來看一下代碼吧:
public class ScrollLayout extends LinearLayout implements GestureDetector.OnGestureListener{
private int offset; //相對距離
private GestureDetector gestureDetector; //手勢事件
private int childWidth; //子View的寬度
private int childCount; //子視圖的數量
private int defaultWindow; //默認窗口
private boolean setShareWindowFlag=false; // 保證默認窗口的設置只執行一次
public ScrollLayout(Context context) {
super(context);
init();
}
public ScrollLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
//獲取定義的defaultWindow的值
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyScrollWindow);
defaultWindow = typedArray.getInteger(R.styleable.MyScrollWindow_defaultWindow,0);
}
private void init(){
gestureDetector = new GestureDetector(this.getContext(),this);
}
//返回值為true 才能觸發 手勢事件
public boolean onDown(MotionEvent e) {
return true;
}
public void onShowPress(MotionEvent e) { }
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
//順手勢滑動
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//獲取滑動的距離
offset = (int) (offset - distanceX);
//防止滑出邊界
if(offset>0){
offset=0;
}else if(offset < -1*childWidth*(childCount-1)){
offset= -1*childWidth*(childCount-1);
}
//重繪布局
requestLayout();
return true;
}
public void onLongPress(MotionEvent e) {
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
//設置布局文件的寬高和每個桌面的寬高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
//給每個桌面設置和屏幕相同的寬度和高度
int childCount = getChildCount();
for(int i=0;i<childCount;i++){
getChildAt(i).measure(widthMeasureSpec,heightMeasureSpec);
}
}
//設置布局
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
childCount = getChildCount(); //獲取子視圖數
childWidth = childCount > 0? getChildAt(0).getMeasuredWidth():0; //獲取字節點的寬度
if(!setShareWindowFlag&&defaultWindow>=0&&defaultWindow<=childCount-1){
//設置默認窗口的左端距離
offset = -1*defaultWindow*childWidth;
setShareWindowFlag=true;
}
//設置距離(0,0)點X軸方向的初始距離
int left = 0+offset;
for (int i = 0; i < childCount ; i ++){
//設置每個子視圖在布局中的位置
View child = getChildAt(i);
if(child.getVisibility()!=View.GONE){
child.layout(left,0,childWidth+left,child.getMeasuredHeight());
left = left + childWidth;
}
}
}
//觸屏事件
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = gestureDetector.onTouchEvent(event);
if(event.getAction()==MotionEvent.ACTION_UP){
//當手指抬起來時 判斷滑動距離顯示整個子視圖
showOneDesktop();
}
return result;
}
//判斷當手指抬起時顯示那個桌面
private void showOneDesktop(){
int index = Math.abs(offset)/childWidth;
if(Math.abs(offset)-index*childWidth>childWidth/2){
index++;
}
offset = offset > 0 ? index*childWidth : -1*index*childWidth;
requestLayout();
}
} 在這段代碼中使用到的attrs.xml文件:<resources>
<declare-styleable name="MyScrollWindow">
<attr name="defaultWindow" format="integer"/>
</declare-styleable>
</resources>使用: <?xml version="1.0" encoding="utf-8"?>
<com.wxg.scroll_window.view.ScrollLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:demo="http://schemas.android.com/apk/res/com.wxg.scroll_window"
android:id="@+id/testLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
demo:defaultWindow="1"
>
<FrameLayout
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:background="#cccccc">
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="1"/>
</FrameLayout>
<FrameLayout
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:background="#ffffff">
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="2"/>
</FrameLayout>
<FrameLayout
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:background="#bcbcbc">
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="3"/>
</FrameLayout>
</com.wxg.scroll_window.view.ScrollLayout> 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!