码迷,mamicode.com
首页 > 其他好文 > 详细

自定义控件学习——防qq侧滑栏

时间:2016-08-06 23:32:38      阅读:402      评论:0      收藏:0      [点我收藏+]

标签:

效果

技术分享

 

主要步骤:

1. 在xml布局里摆放内容. include
    2. 在自定义ViewGroup里, 进行measure测量, layout布局
    3. 响应用户的触摸事件
    4. int scrollX = (int) (downX - moveX);
    5. getScrollX()获取当前滚动到的位置
    6. 平滑动画

 

先看布局

layout_left

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="240dp"
            android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@drawable/menu_bg">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:background="@drawable/selector_bg"
       android:drawablePadding="10dp"
        android:gravity="center_vertical"
        android:text="新闻"
        android:clickable="true"
        android:textColor="#ADCFD6"
        android:drawableLeft="@drawable/tab_news"
        android:textSize="18sp"/>

    </LinearLayout>
</ScrollView>

 

layout_content

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="#FFFFFF"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="@drawable/top_bar_bg">
        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/main_back"
            android:background="@null"/>
        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="@drawable/top_bar_divider"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="每日新闻"
            android:textSize="25sp"
            android:layout_gravity="center"/>

    </LinearLayout>

</LinearLayout>

 

activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.xw.mystudeydemo.MainActivity">

<com.example.mystudydemo.SlideMeun
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <include layout="@layout/layout_left"/>
    <include layout="@layout/layoit_content"/>
</com.example.mystudydemo.SlideMeun>
</RelativeLayout>

 

布局中需要注意的是,layout_content中我们把整体布局背景设置成了android:background="#FFFFFF",这是因为我们需要他完全遮住下面的那层layout_left.xml

 

layout_left的状态选择器

 

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@color/bg_pressed"/>
    <item android:drawable="@android:color/transparent"/>
</selector>

 

 

 

二,写自定义控件

 

 

package com.example.mystudydemo;
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 xw on 2016/8/6.
 */
public class SlideMeun  extends ViewGroup{
    private float downX;
    private float moveX;
    private Scroller scroller;
    /**
 * 侧滑面板控件, 抽屉面板.
 * @author poplar
 * 
 *   测量             摆放     绘制
  measure   ->  layout  ->  draw
      |           |          |
  onMeasure -> onLayout -> onDraw 重写这些方法, 实现自定义控件
  
      View流程
      onMeasure() (在这个方法里指定自己的宽高) -> onDraw() (绘制自己的内容)
      
      ViewGroup流程
      onMeasure() (指定自己的宽高, 所有子View的宽高)-> onLayout() (摆放所有子View) -> onDraw() (绘制内容)
 *
 */

    public SlideMeun(Context context) {
        super(context);
        init(context);
    }

    public SlideMeun(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

   

    public SlideMeun(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }
     private void init(Context context) {
         // 初始化滚动器
        scroller=new Scroller(context);
        }
   

    /**
     * 测量并设置 所有子View的宽高
     * widthMeasureSpec: 当前控件的宽度测量规则
     * heightMeasureSpec: 当前控件的高度测量规则
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
       // 指定左面板的宽高
        View leftMenu=getChildAt(0);
        leftMenu.measure(leftMenu.getLayoutParams().width,heightMeasureSpec);
            // 指定主面板的宽高
        View mainMenu=getChildAt(1);
        mainMenu.measure(mainMenu.getLayoutParams().width,heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
   
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
      // 摆放内容, 左面板,隐藏
        View leftMenu=getChildAt(0);
        leftMenu.layout(-leftMenu.getMeasuredWidth(),0,0,b);

        // 主面板
        View mainMenu=getChildAt(1);
        mainMenu.layout(l,t,r,b);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
              moveX =event.getX();
              
                   // 将要发生的偏移量/变化量
               int scrollX=(int)(downX-moveX);
               // 计算将要滚动到的位置, 判断是否会超出去, 超出去了.不执行scrollBy
                // getScrollX() 当前滚动到的位置
               int newposition=getScrollX()+scrollX;
               if(newposition<-getChildAt(0).getMeasuredWidth()){   // 限定左边界
                   scrollTo(-getChildAt(0).getMeasuredWidth(), 0);
               }
               else if(newposition>0){    // 限定右边界
                   scrollTo(0, 0);
               }
               else{
                   // 让变化量生效
               scrollBy(scrollX,0);
               }
                downX=moveX;
                break;
            case MotionEvent.ACTION_UP:
            
                int leftcenter=-(int)(getChildAt(0).getMeasuredWidth()/2.0f);
                int startX=getScrollX();
                int dx=0;
                    // 根据当前滚动到的位置, 和左面板的一半进行比较
                if(startX<leftcenter){
                    // 打开, 切换成菜单面板
                    dx=-getChildAt(0).getMeasuredWidth()-startX;
                 
                    
                    
                }
                else{
                    // 关闭, 切换成主面板
                     dx=0-startX;
                     
                }
                int duration=Math.abs(dx*10);
                scroller.startScroll(startX, 0, dx, 0, duration);
                invalidate(); //重绘界面 -> drawChild() -> computeScroll();
                break;
                
                
            default:
                break;
        }

        return true;//消费事件
    }
    
    @Override  ////2. 维持动画的继续
    public void computeScroll() {
        
        super.computeScroll();
        if(scroller.computeScrollOffset()){
            int currX=scroller.getCurrX();
            scrollTo(currX, 0);
            invalidate();
        }
    }
}

 

 

 

三, MainActivity

package com.example.mystudydemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
       
        
    }

  
}

 

自定义控件学习——防qq侧滑栏

标签:

原文地址:http://www.cnblogs.com/xurui1995/p/5745111.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!