alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Android example source code file (IconMenuItemView.java)

This example Android source code file (IconMenuItemView.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Android by Example" TM.

Java - Android tags/keywords

android, attributeset, charsequence, content, context, drawable, drawing, iconmenuitemview, iconmenuview, menuitemimpl, menuview_itemtextappearance, no_alpha, override, paint, rect, string, textview, typedarray, ui, view

The IconMenuItemView.java Android example source code

/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * 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 com.android.internal.view.menu;

import com.android.internal.view.menu.MenuBuilder.ItemInvoker;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewDebug;
import android.widget.TextView;
import android.text.Layout;

/**
 * The item view for each item in the {@link IconMenuView}.  
 */
public final class IconMenuItemView extends TextView implements MenuView.ItemView {
    
    private static final int NO_ALPHA = 0xFF;
    
    private IconMenuView mIconMenuView;
    
    private ItemInvoker mItemInvoker;
    private MenuItemImpl mItemData; 
    
    private Drawable mIcon;
    
    private int mTextAppearance;
    private Context mTextAppearanceContext;
    
    private float mDisabledAlpha;

    private Rect mPositionIconAvailable = new Rect();
    private Rect mPositionIconOutput = new Rect();
    
    private boolean mShortcutCaptionMode;
    private String mShortcutCaption;
    
    private static String sPrependShortcutLabel;

    public IconMenuItemView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs);

        if (sPrependShortcutLabel == null) {
            /*
             * Views should only be constructed from the UI thread, so no
             * synchronization needed
             */
            sPrependShortcutLabel = getResources().getString(
                    com.android.internal.R.string.prepend_shortcut_label);
        }
        
        TypedArray a =
            context.obtainStyledAttributes(
                attrs, com.android.internal.R.styleable.MenuView, defStyle, 0);

        mDisabledAlpha = a.getFloat(
                com.android.internal.R.styleable.MenuView_itemIconDisabledAlpha, 0.8f);
        mTextAppearance = a.getResourceId(com.android.internal.R.styleable.
                                          MenuView_itemTextAppearance, -1);
        mTextAppearanceContext = context;
        
        a.recycle();
    }
    
    public IconMenuItemView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * Initializes with the provided title and icon
     * @param title The title of this item
     * @param icon The icon of this item
     */
    void initialize(CharSequence title, Drawable icon) {
        setClickable(true);
        setFocusable(true);

        if (mTextAppearance != -1) {
            setTextAppearance(mTextAppearanceContext, mTextAppearance);
        }

        setTitle(title);
        setIcon(icon);
    }
    
    public void initialize(MenuItemImpl itemData, int menuType) {
        mItemData = itemData;

        initialize(itemData.getTitleForItemView(this), itemData.getIcon());
        
        setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
        setEnabled(itemData.isEnabled());
    }

    @Override
    public boolean performClick() {
        // Let the view's click listener have top priority (the More button relies on this)
        if (super.performClick()) {
            return true;
        }
        
        if ((mItemInvoker != null) && (mItemInvoker.invokeItem(mItemData))) {
            playSoundEffect(SoundEffectConstants.CLICK);
            return true;
        } else {
            return false;
        }
    }
    
    public void setTitle(CharSequence title) {
        
        if (mShortcutCaptionMode) {
            /*
             * Don't set the title directly since it will replace the
             * shortcut+title being shown. Instead, re-set the shortcut caption
             * mode so the new title is shown.
             */
            setCaptionMode(true);
            
        } else if (title != null) {
            setText(title);
        }
    }
    
    void setCaptionMode(boolean shortcut) {
        /*
         * If there is no item model, don't do any of the below (for example,
         * the 'More' item doesn't have a model)
         */
        if (mItemData == null) {
            return;
        }
        
        mShortcutCaptionMode = shortcut && (mItemData.shouldShowShortcut());
        
        CharSequence text = mItemData.getTitleForItemView(this);
        
        if (mShortcutCaptionMode) {
            
            if (mShortcutCaption == null) {
                mShortcutCaption = mItemData.getShortcutLabel();
            }

            text = mShortcutCaption;
        }
        
        setText(text);
    }
    
    public void setIcon(Drawable icon) {
        mIcon = icon;
        
        if (icon != null) {
            
            /* Set the bounds of the icon since setCompoundDrawables needs it. */
            icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
            
            // Set the compound drawables
            setCompoundDrawables(null, icon, null, null);
            
            // When there is an icon, make sure the text is at the bottom
            setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);

            /*
             * Request a layout to reposition the icon. The positioning of icon
             * depends on this TextView's line bounds, which is only available
             * after a layout.
             */  
            requestLayout();
        } else {
            setCompoundDrawables(null, null, null, null);
            
            // When there is no icon, make sure the text is centered vertically
            setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
        }
    }

    public void setItemInvoker(ItemInvoker itemInvoker) {
        mItemInvoker = itemInvoker;
    }
    
    @ViewDebug.CapturedViewProperty(retrieveReturn = true)
    public MenuItemImpl getItemData() {
        return mItemData;
    }

    @Override
    public void setVisibility(int v) {
        super.setVisibility(v);
        
        if (mIconMenuView != null) {
            // On visibility change, mark the IconMenuView to refresh itself eventually
            mIconMenuView.markStaleChildren();
        }
    }
    
    void setIconMenuView(IconMenuView iconMenuView) {
        mIconMenuView = iconMenuView;
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();

        if (mItemData != null && mIcon != null) {
            // When disabled, the not-focused state and the pressed state should
            // drop alpha on the icon
            final boolean isInAlphaState = !mItemData.isEnabled() && (isPressed() || !isFocused());
            mIcon.setAlpha(isInAlphaState ? (int) (mDisabledAlpha * NO_ALPHA) : NO_ALPHA);
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        
        positionIcon();
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int before, int after) {
        super.onTextChanged(text, start, before, after);

        // our layout params depend on the length of the text
        setLayoutParams(getTextAppropriateLayoutParams());
    }

    /**
     * @return layout params appropriate for this view.  If layout params already exist, it will
     *         augment them to be appropriate to the current text size.
     */
    IconMenuView.LayoutParams getTextAppropriateLayoutParams() {
        IconMenuView.LayoutParams lp = (IconMenuView.LayoutParams) getLayoutParams();
        if (lp == null) {
            // Default layout parameters
            lp = new IconMenuView.LayoutParams(
                    IconMenuView.LayoutParams.MATCH_PARENT, IconMenuView.LayoutParams.MATCH_PARENT);
        }

        // Set the desired width of item
        lp.desiredWidth = (int) Layout.getDesiredWidth(getText(), getPaint());

        return lp;
    }

    /**
     * Positions the icon vertically (horizontal centering is taken care of by
     * the TextView's gravity).
     */
    private void positionIcon() {
        
        if (mIcon == null) {
            return;
        }
        
        // We reuse the output rectangle as a temp rect
        Rect tmpRect = mPositionIconOutput;
        getLineBounds(0, tmpRect);
        mPositionIconAvailable.set(0, 0, getWidth(), tmpRect.top);
        Gravity.apply(Gravity.CENTER_VERTICAL | Gravity.LEFT, mIcon.getIntrinsicWidth(), mIcon
                .getIntrinsicHeight(), mPositionIconAvailable, mPositionIconOutput);
        mIcon.setBounds(mPositionIconOutput);
    }

    public void setCheckable(boolean checkable) {
    }

    public void setChecked(boolean checked) {
    }

    public void setShortcut(boolean showShortcut, char shortcutKey) {
        
        if (mShortcutCaptionMode) {
            /*
             * Shortcut has changed and we're showing it right now, need to
             * update (clear the old one first).
             */
            mShortcutCaption = null;
            setCaptionMode(true);
        }
    }

    public boolean prefersCondensedTitle() {
        return true;
    }

    public boolean showsIcon() {
        return true;
    }

}

Other Android examples (source code examples)

Here is a short list of links related to this Android IconMenuItemView.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.