ModeSwitchView(用于相机中横向切换状态)

本文介绍了一个自定义的Android模式切换视图组件,该组件通过滑动选择不同的模式,包括文档、身份证、白板和文稿模式。文章详细阐述了组件的工作原理、布局配置及触摸事件处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

核心类

public class ModeSwitchView extends LinearLayout implements View.OnClickListener {
    private ModeScroller mCameraScroller;
    private TextView document;
    private TextView idcard;
    private TextView whiteboard;
    private TextView paperwork;

    public static final int MODE_DOCUMENT = 0;
    public static final int MODE_IDCARD = 1;
    public static final int MODE_WHITEBOARD = 2;
    public static final int MODE_PAPERWORK = 3;

    private List<Integer> mModeList = new ArrayList<>();
    private int mCurrentSelectedIndex = 0;

    public void setCurrentSelectedIndex(int index) {
        mCurrentSelectedIndex = index;
    }

    public int getCurrentSelectedIndex() {
        return mCurrentSelectedIndex;
    }

    private OnStateChangeListener mListener;

    public interface OnStateChangeListener {
        void onStateChange(int state);
    }

    public void setOnStateChangeListener(OnStateChangeListener mListener) {
        this.mListener = mListener;
    }

    public ModeSwitchView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mModeList.add(MODE_DOCUMENT);
        mModeList.add(MODE_IDCARD);
        mModeList.add(MODE_WHITEBOARD);
        mModeList.add(MODE_PAPERWORK);

        LayoutInflater.from(context).inflate(R.layout.argus_mode_scroller_layout, this, true);
        mCameraScroller = (ModeScroller) findViewById(R.id.camera_scroller);
        mCameraScroller.setCallback(new ModeScroller.Callback() {
            @Override
            public int getSelectedIndex() {
                return getCurrentSelectedIndex();
            }
        });

        document = (TextView) mCameraScroller.findViewById(R.id.document);
        idcard = (TextView) mCameraScroller.findViewById(R.id.idcard);
        whiteboard = (TextView) mCameraScroller.findViewById(R.id.whiteboard);
        paperwork = (TextView) mCameraScroller.findViewById(R.id.paperwork);

        document.setOnClickListener(this);
        idcard.setOnClickListener(this);
        whiteboard.setOnClickListener(this);
        paperwork.setOnClickListener(this);
    }

    public void moveLeft() {
        if (getCurrentSelectedIndex() <= 0) {
            return;
        }
        mCameraScroller.leftIndex = getCurrentSelectedIndex() - 1;
        mCameraScroller.rightIndex = getCurrentSelectedIndex();
        int dx = Math.round((mCameraScroller.getChildAt(mCameraScroller.leftIndex).getWidth() + mCameraScroller.getChildAt(mCameraScroller.rightIndex).getWidth()) / 2.0F);
        if (!mCameraScroller.mScroller.isFinished()) {
            return;
        }
        mCameraScroller.mScroller.startScroll(mCameraScroller.getScrollX(), 0, -dx, 0, mCameraScroller.duration);
        mCameraScroller.scrollToNext(mCameraScroller.rightIndex, mCameraScroller.leftIndex);
        setCurrentSelectedIndex(getCurrentSelectedIndex() - 1);
        mCameraScroller.invalidate();
        notifyUI(getCurrentSelectedIndex());
    }

    public void moveRight() {
        if (getCurrentSelectedIndex() >= mModeList.size() - 1) {
            return;
        }
        mCameraScroller.leftIndex = getCurrentSelectedIndex();
        mCameraScroller.rightIndex = getCurrentSelectedIndex() + 1;
        int dx = Math.round((mCameraScroller.getChildAt(mCameraScroller.leftIndex).getWidth() + mCameraScroller.getChildAt(mCameraScroller.rightIndex).getWidth()) / 2.0F);
        if (!mCameraScroller.mScroller.isFinished()) {
            return;
        }
        mCameraScroller.mScroller.startScroll(mCameraScroller.getScrollX(), 0, dx, 0, mCameraScroller.duration);
        mCameraScroller.scrollToNext(mCameraScroller.leftIndex, mCameraScroller.rightIndex);
        setCurrentSelectedIndex(getCurrentSelectedIndex() + 1);
        mCameraScroller.invalidate();
        notifyUI(getCurrentSelectedIndex());
    }

    public void moveTo(int index) {
        int selectedIndex = getCurrentSelectedIndex();
        View selectView = mCameraScroller.getChildAt(selectedIndex);
        View dstView = mCameraScroller.getChildAt(index);
        int dx = Math.abs((int) ((selectView.getRight() - selectView.getWidth() / 2f) - (dstView.getRight() - dstView.getWidth() / 2f)));
        if (index < selectedIndex) {
            dx = -dx;
        }
        if (!mCameraScroller.mScroller.isFinished()) {
            return;
        }
        mCameraScroller.mScroller.startScroll(mCameraScroller.getScrollX(), 0, dx, 0, mCameraScroller.duration);
        mCameraScroller.scrollToNext(selectedIndex, index);
        setCurrentSelectedIndex(index);
        mCameraScroller.invalidate();
        notifyUI(index);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.document:
                moveTo(MODE_DOCUMENT);
                break;
            case R.id.idcard:
                moveTo(MODE_IDCARD);
                break;
            case R.id.whiteboard:
                moveTo(MODE_WHITEBOARD);
                break;
            case R.id.paperwork:
                moveTo(MODE_PAPERWORK);
                break;
        }
    }

    public void setCurrentMode(int index) {
        if (index > mModeList.size() - 1 || index < 0) {
            return;
        }
        moveTo(index);
    }

    private void notifyUI(int index) {
        if (mListener != null) {
            mListener.onStateChange(index);
        }
    }

    private boolean mScrolling;
    private float touchDownX;
    private float touchDownY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchDownX = event.getX();
                touchDownY = event.getY();
                mScrolling = false;
                break;
            case MotionEvent.ACTION_MOVE:
                int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
                if (Math.abs(touchDownX - event.getX()) >= slop || Math.abs(touchDownY - event.getY()) >= slop) {
                    mScrolling = true;
                } else {
                    mScrolling = false;
                }
                break;
            case MotionEvent.ACTION_UP:
                mScrolling = false;
                break;
        }
        return mScrolling;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                return true;
            case MotionEvent.ACTION_UP:
                if (this.getVisibility() == View.VISIBLE) {
                    int deltaX = (int) (event.getX() - touchDownX);
                    int deltaY = (int) (event.getY() - touchDownY);
                    int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
                    if (Math.abs(deltaX) > slop) {
                        // swipe left
                        if (deltaX < -Math.abs(deltaY) * 2) {
                            moveRight();
                        }
                        // swipe right
                        if (deltaX >= Math.abs(deltaY) * 2) {
                            moveLeft();
                        }
                    }
                }
                break;
        }

        return super.onTouchEvent(event);
    }
}
public class ModeScroller extends ViewGroup {

    public Scroller mScroller;
    public int leftIndex;
    public int rightIndex;
    public int duration = 250;

    public ModeScroller(Context context, AttributeSet attrs) {
        super(context, attrs);
        mScroller = new Scroller(context);
    }

    public interface Callback {
        int getSelectedIndex();
    }
    private Callback mCallback;

    public void setCallback(Callback callback) {
        mCallback = callback;
    }

    public final void scrollToNext(int preIndex, int nextIndex) {
        TextView selectedText = (TextView) getChildAt(preIndex);
        if (selectedText != null) {
            selectedText.setTextColor(getResources().getColor(android.R.color.white));
        }
        selectedText = (TextView) getChildAt(nextIndex);
        if (selectedText != null) {
            selectedText.setTextColor(getResources().getColor(R.color.chosen_color_yellow));
        }
    }

    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
        super.computeScroll();
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
    }

    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        int cCount = getChildCount();
        int selectedMode = mCallback.getSelectedIndex();
        Log.d("wyl", "selectedMode = " + selectedMode);
        int widthOffset = 0;

        for (int i = 0; i < cCount; i++) {
            View childView = getChildAt(i);
            if (i < selectedMode) {
                widthOffset += childView.getMeasuredWidth();
            }
        }

        int childLeft = 0;
        int childRight = 0;

        for (int i = 0; i < cCount; i++) {
            View childView = getChildAt(i);
            if (i != 0) {
                View preView = getChildAt(i - 1);
                childLeft = preView.getRight();
                childRight = childLeft + childView.getMeasuredWidth();
            } else {
                childLeft = (getWidth() - getChildAt(selectedMode).getMeasuredWidth()) / 2 - widthOffset + mScroller.getFinalX();
                childRight = childLeft + childView.getMeasuredWidth();
            }
            childView.layout(childLeft, top, childRight, bottom);
        }

        TextView indexText = (TextView) getChildAt(selectedMode);
        indexText.setTextColor(getResources().getColor(R.color.chosen_color_yellow));
    }
}

布局文件

<?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:orientation="vertical">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="3.0dip"
        android:background="@drawable/camera_mode_index_icon_point" />

    <com.xxx.xxx.ModeScroller
        android:id="@+id/camera_scroller"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_marginTop="-3dp">

        <TextView
            android:id="@+id/document"
            style="@style/ModeScrollerBar"
            android:text="@string/argus_text_document" />

        <TextView
            android:id="@+id/idcard"
            style="@style/ModeScrollerBar"
            android:text="@string/argus_text_idcard" />

        <TextView
            android:id="@+id/whiteboard"
            style="@style/ModeScrollerBar"
            android:text="@string/argus_text_whiteboard" />

        <TextView
            android:id="@+id/paperwork"
            style="@style/ModeScrollerBar"
            android:text="@string/argus_text_paperwork" />
    </com.xxx.xxx.ModeScroller>
</LinearLayout>

style

<style name="ModeScrollerBar">
        <item name="android:textSize">13sp</item>
        <item name="android:textColor">@android:color/white</item>
        <item name="android:gravity">center</item>
        <item name="android:paddingLeft">10dp</item>
        <item name="android:paddingRight">10dp</item>
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
    </style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值