zoukankan      html  css  js  c++  java
  • View 的 focus 和 selected 状态, TabContainer实现

    View的 isFocusableInTouchMode() 默认是 false, 需调用 setFocusableInTouchMode(true) 才为true
    要让 button 等 view 调用 requestFocus 方法起作用, 需要 isFocusableInTouchMode() 为true才行。

    setFocusable(false) 会到导致 isFocusable() 和 isFocusableInTouchMode() 都为false,
    要设为true只能分别调用 setFocusable(true) 和 setFocusableInTouchMode(true)

    只能有一个View得到焦点,其他的View将失去焦点.

    Selected
    可以有多个View同时处于 Selected状态。

    View 的 setSelected方法,会调用 dispatchSetSelected 向子View传递 select状态。

    public void setSelected(boolean selected) {
            if (((mPrivateFlags & SELECTED) != 0) != selected) {
                mPrivateFlags = (mPrivateFlags & ~SELECTED) | (selected ? SELECTED : 0);
                if (!selected) resetPressedState();
                invalidate();
                refreshDrawableState();
                dispatchSetSelected(selected);
            }
    }

    ViewGroup 的 dispatchSetSelected 方法。

    public void dispatchSetSelected(boolean selected) {
            final View[] children = mChildren;
            final int count = mChildrenCount;
            for (int i = 0; i < count; i++) {
                children[i].setSelected(selected);
            }
    }

    Selector

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/black" android:state_selected="true"/>
        <item android:drawable="@drawable/white"/>
    </selector>

    ViewGroup 有多个重载的 addView方法
    在xml布局文件里面添加的子View,是通过下面这个重载方法加到ViewGroup中的。

    public void addView(View child, ViewGroup.LayoutParams params);

    利用上述机制,可以简单的实现一个类似 TabWidget 的 tab 切换容器,支持用 selector 改变 tabView 和 tabView 子 View 的背景.

    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.LinearLayout;
    
    public class TabContainer extends LinearLayout {
        private int mCurrentTab = -1;
    
        public TabContainer(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public void setCurrentTab(int index) {
            if (getChildCount() == 0) {
                return;
            }
    
            if (index >= 0 && index <= getChildCount() - 1) {
                getChildAt(index).performClick();
            }
        }
    
        @Override
        public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) {
            super.addView(child, index, params);
    
            child.setOnClickListener(mOnClickListener);
            child.setSelected(false);
        }
    
        private View.OnClickListener mOnClickListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                int index = indexOfChild(v);
                if (index != mCurrentTab) {
                    if (mCurrentTab >= 0) {
                        getChildAt(mCurrentTab).setSelected(false);
                    }
                    getChildAt(index).setSelected(true);
                    mCurrentTab = index;
    
                    if (mOnTabSelectChangeListener != null) {
                        mOnTabSelectChangeListener.onTabSelectChanged(index, v);
                    }
                }
            }
        };
    
        private OnTabSelectChangeListener mOnTabSelectChangeListener;
    
        public void setOnTabSelectChangeListener(OnTabSelectChangeListener listener) {
            mOnTabSelectChangeListener = listener;
        }
    
        public interface OnTabSelectChangeListener {
            public void onTabSelectChanged(int index, View tab);
        }
    }
    View Code
  • 相关阅读:
    Vue 2.0学习(三)指令与事件
    Vue 2.0学习(二)数据绑定
    Vue 2.0学习(一)简介
    大数据入门学习(一):初识大数据
    Knockout.js(四):自定义绑定
    03 Python基础
    02 测试环境的搭建
    01 自动化测试基础
    第29章 项目10:DIY街机游戏
    第27章 项目8:使用XML-RPC进行文件共享
  • 原文地址:https://www.cnblogs.com/zijianlu/p/3421722.html
Copyright © 2011-2022 走看看