org.connectbot.views.CheckableMenuItem.java Source code

Java tutorial

Introduction

Here is the source code for org.connectbot.views.CheckableMenuItem.java

Source

/*
 * ConnectBot: simple, powerful, open-source SSH client for Android
 * Copyright 2016 Kenny Root, Jeffrey Sharkey
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.connectbot.views;

import java.util.List;

import org.connectbot.R;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.support.v4.widget.ExploreByTouchHelper;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * Created by kenny on 5/31/16.
 */
public class CheckableMenuItem extends RelativeLayout {
    private static final String ACCESSIBILITY_EVENT_CLASS_NAME = "android.widget.Switch";

    private final Rect mPlaceHolderRect = new Rect(0, 0, 1, 1);
    private static final String PLACEHOLDER_STRING = "";

    private final View mRootView;
    private final TextView mTitle;
    private final TextView mSummary;
    private final SwitchCompat mSwitch;
    private final ExploreByTouchHelper mAccessHelper;

    public CheckableMenuItem(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CheckableMenuItem(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mRootView = inflate(context, R.layout.view_checkablemenuitem, this);

        mTitle = (TextView) mRootView.findViewById(R.id.title);
        mSummary = (TextView) mRootView.findViewById(R.id.summary);
        mSwitch = (SwitchCompat) findViewById(R.id.checkbox_switch);

        setFocusable(true);

        mAccessHelper = new ExploreByTouchHelper(this) {
            private final Rect mTmpRect = new Rect();

            @Override
            protected int getVirtualViewAt(float x, float y) {
                return HOST_ID;
            }

            @Override
            protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
            }

            @Override
            protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
                if (virtualViewId != HOST_ID) {
                    // TODO(kroot): remove this when the bug is fixed.
                    event.setContentDescription(PLACEHOLDER_STRING);
                    return;
                }

                event.setContentDescription(mTitle.getText() + " " + mSummary.getText());
                event.setClassName(ACCESSIBILITY_EVENT_CLASS_NAME);
                event.setChecked(isChecked());
            }

            @Override
            protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfoCompat node) {
                if (virtualViewId != HOST_ID) {
                    // TODO(kroot): remove this when the bug is fixed.
                    node.setBoundsInParent(mPlaceHolderRect);
                    node.setContentDescription(PLACEHOLDER_STRING);
                    return;
                }

                mTmpRect.set(0, 0, CheckableMenuItem.this.getWidth(), CheckableMenuItem.this.getHeight());
                node.setBoundsInParent(mTmpRect);

                node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
                node.setClassName(ACCESSIBILITY_EVENT_CLASS_NAME);
                node.setCheckable(true);
                node.setChecked(isChecked());

                node.addChild(mTitle);
                node.addChild(mSummary);
            }

            @Override
            protected boolean onPerformActionForVirtualView(int virtualViewId, int action, Bundle arguments) {
                if (virtualViewId != HOST_ID) {
                    return false;
                }

                if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
                    mSwitch.toggle();
                    sendAccessibilityEvent(mRootView, AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
                    return true;
                }

                return false;
            }
        };
        ViewCompat.setAccessibilityDelegate(mRootView, mAccessHelper);

        setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mSwitch.toggle();
            }
        });

        if (attrs != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CheckableMenuItem, 0, 0);

            @DrawableRes
            int iconRes = typedArray.getResourceId(R.styleable.CheckableMenuItem_android_icon, 0);
            @StringRes
            int titleRes = typedArray.getResourceId(R.styleable.CheckableMenuItem_android_title, 0);
            @StringRes
            int summaryRes = typedArray.getResourceId(R.styleable.CheckableMenuItem_summary, 0);

            typedArray.recycle();

            ImageView icon = (ImageView) mRootView.findViewById(R.id.icon);
            mTitle.setText(titleRes);
            if (iconRes != 0) {
                Resources resources = context.getResources();
                Resources.Theme theme = context.getTheme();
                Drawable iconDrawable = VectorDrawableCompat.create(resources, iconRes, theme);

                icon.setImageDrawable(iconDrawable);
            }
            if (summaryRes != 0) {
                mSummary.setText(summaryRes);
            }
        }
    }

    public boolean isChecked() {
        return mSwitch.isChecked();
    }

    public void setChecked(boolean checked) {
        mAccessHelper.sendAccessibilityEvent(mRootView, AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
        mSwitch.setChecked(checked);
    }

    public void toggle() {
        mAccessHelper.sendAccessibilityEvent(mRootView, AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
        mSwitch.toggle();
    }

    public void setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener listener) {
        mSwitch.setOnCheckedChangeListener(listener);
    }
}