コントロールのカスタマイズ方法

4945 ワード

コントロールのカスタマイズ方法
1、カスタム属性の宣言と抽出
  • 1、分析に必要なカスタム属性
  • 2、res/values/attrs.xmlファイル定義宣言
  • 
    
        
        
        
        
        
            
            
            
            
        
    
    
  • 3、layout xmlファイルでの使用
  • 4、Viweの構築方法で取得する
  •  TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ChangeTextIconSizeWithColor);
            int n = a.getIndexCount();
            //         
            for (int i = 0; i < n; i++) {
                int attr = a.getIndex(i);
                switch (attr) {
                    case R.styleable.ChangeTextIconSizeWithColor_color:
                        mColor = a.getColor(attr, 0xFF3343);
                        break;
                    case R.styleable.ChangeTextIconSizeWithColor_icon:
                        BitmapDrawable drawable = (BitmapDrawable) a.getDrawable(attr);
                        mBitmap = drawable.getBitmap();
                        break;
                    case R.styleable.ChangeTextIconSizeWithColor_text:
                        mText = a.getString(attr);
                        break;
                    case R.styleable.ChangeTextIconSizeWithColor_text_size:
                        mTextSize = a.getDimension(attr, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 11, getResources().getDisplayMetrics()));
    
                        break;
                }
            }
            //    
            a.recycle();
    

    2、測量onMeasure()
  • 1、測定モード:
  • EXACTRY
  • および正確な値モードでは、コントロールのlayout_widthプロパティまたはlayout_heightプロパティが特定の数値に指定されている場合、android:layout_width="100dp".

  • AT_MOST
  • 最大値モード、コントロールのlayout_widthプロパティまたはlayout_heightプロパティ指定wrap_contentの場合、コントロールのサイズは一般的にコントロールのサブ空間の内容の変化に伴って変化し、この場合、コントロールのサイズは親コントロールが許容する最大サイズを操作しない限り
  • である.
  • UNSPECIFIED
  • 計測のパターンを指定せず、どれだけ大きくしたいか(一般的にScrollViewまたはListViewで)
  • .

  • 2、MeasureSpec(サブクラス)
  • このクラスを通して、Viewの測定モードと、Viewが描画したいサイズ
  • を取得する.
  • の下のコードはテンプレートで、基本的に何の変化もありません
  • 
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //super.onMeasure(widthMeasureSpec,heightMeasureSpec);//                
            setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
        }
    
    
       /**
         *        
         *
         * @param heightMeasureSpec
         * @return
         */
        private int measureHeight(int heightMeasureSpec) {
            int result = 0;
            //  
            int mode = MeasureSpec.getMode(heightMeasureSpec);
            //  
            int size = MeasureSpec.getSize(heightMeasureSpec);
            if (mode == MeasureSpec.EXACTLY) {
                result = size;
            } else {
                result = 100;  //            
                if (mode == MeasureSpec.AT_MOST) {
                    result = Math.min(result, size);
                }
            }
    
            return result;
        }
    

    幅を取得するコードと高さを取得する差は多くありません.ここでは書きません.ここで、高さと幅の値のカスタマイズができますか.
    3、レイアウトonLayout(ViewGroup)
  • 1、決定子Viewの位置
  • 2、できるだけonMeasureの中のいくつかの方法の操作をこの方法に移動する(onLayout()
  • 3、requestLayout()
  •  @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            final int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                //     view
                final View child = getChildAt(i);
                if (child.getVisibility() == GONE) {
                    continue;
                }
    
                left = caculateChildLeft();//  childView  layout     x  
                top = caculateChildTop();//  childView  layout     y  
    
                child.layout(left, top, left + childWidth, top + childHeight);
            }
        }
    

    4、描画onDraw
  • 1、描画コンテンツ領域
  • 2、invalidate()(UIスレッド)、postInvalidate()(サブスレッド)
  • 3、Canvas.drawXXX()
  • 4、translate、rotate、scale、skew
  • 5、sava()、restore()

  • 5、onTouchEvent
  • 1、タッチケース
  • ACTION_DOWN
  • ACTION_MOVE
  • ACTION_UP

  • 2、マルチタッチ(どれが制御されているかを決めるのがActivePointer)
  • ACTION_POINTER_DOWN
  • ACTION_POINTER_UP

  • 3、parent.requestDisallowInterceptTouchEvent(true)(親コントロールにイベントをブロックしないでサブコントロールに渡すように要求)
  • 4、VelocityTracker

  • 6、onInterceptTouchEvent(ViewGroup)
  • 1、タッチケース
  • ACTION_DOWN
  • ACTION_MOVE
  • ACTION_UP

  • 2、マルチタッチ(どれが制御されているかを決めるのがActivePointer)
  • ACTION_POINTER_DOWN
  • ACTION_POINTER_UP

  • 3、このジェスチャー
  • をブロックするか否かを決定する.