com.landenlabs.all_devtool.IconBaseFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.landenlabs.all_devtool.IconBaseFragment.java

Source

package com.landenlabs.all_devtool;

/*
 * Copyright (c) 2016 Dennis Lang (LanDen Labs) landenlabs@gmail.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
 * following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @author Dennis Lang  (3/21/2015)
 * @see http://LanDenLabs.com/
 *
 */

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

import com.landenlabs.all_devtool.util.Ui;
import com.landenlabs.all_devtool.util.Utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

/**
 * Base class for Icon asset display.
 * <p/>
 * <ul>
 * <li> scrollable list of image assets
 * <li> click on row to get detail asset information
 * </ul>
 *
 * @author Dennis Lang
 */
public abstract class IconBaseFragment extends DevFragment {

    final ArrayList<IconInfo> m_list = new ArrayList<IconInfo>();
    ListView m_listView;
    FragmentActivity m_context;
    int m_backgroundColor = -1;
    int m_alternateColor = -1;

    // ============================================================================================
    // Abstract interface

    public abstract void addToList();

    // ============================================================================================
    // Override DevFragment

    @Override
    public List<Bitmap> getBitmaps(int maxHeight) {
        Toast.makeText(getActivity(),
                String.format("Please wait while\n %d items extracted...", m_listView.getCount()),
                Toast.LENGTH_LONG).show();

        return Utils.getListViewAsBitmaps(m_listView, maxHeight);
    }

    // ============================================================================================
    // Override Fragment

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        View rootView = inflater.inflate(R.layout.icon_tab, container, false);
        m_context = this.getActivity();

        m_listView = Ui.viewById(rootView, R.id.iconListView);
        m_listView.removeAllViewsInLayout();

        int[] attrs = { android.R.id.background };
        TypedArray ta = m_context.getTheme().obtainStyledAttributes(attrs);
        m_backgroundColor = ta.getColor(0, -1);
        ta.recycle();
        m_alternateColor = Utils.blend(m_backgroundColor, 0x80d0ffe0);

        m_list.clear();
        addToList();
        Collections.sort(m_list, new Comparator<IconInfo>() {
            @Override
            public int compare(IconInfo icon1, IconInfo icon2) {
                return icon1.fieldStr().compareTo(icon2.fieldStr());
            }
        });

        // TODO - remove duplicates.

        final IconArrayAdapter adapter = new IconArrayAdapter(this.getActivity(), R.layout.icon_list_row,
                R.id.iconName, m_list);
        m_listView.setAdapter(adapter);

        m_listView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                IconInfo iconInfo = (IconInfo) parent.getItemAtPosition(position);
                showIconDialog(iconInfo);
            }
        });

        return rootView;
    }

    // ============================================================================================
    // IconBaseFragment methods

    protected void addIcon(String name, int resId) {
        try {
            m_list.add(new IconInfo(name, resId));
        } catch (Exception ex) {
            // Failed to add asset.
        }
    }

    protected void addAttr(String name, int attrId) {
        int[] attrs = { attrId };
        TypedArray ta = m_context.getTheme().obtainStyledAttributes(attrs);
        Drawable indicator = ta.getDrawable(0);
        ta.recycle();
        m_list.add(new IconInfo(name, indicator));
    }

    // ============================================================================================
    // Internal classes

    private class IconInfo {
        final String m_fieldStr;
        final int m_value;
        final Drawable m_drawable;

        IconInfo(String str1, int value) {
            m_fieldStr = str1;
            m_value = value;
            m_drawable = null;
        }

        IconInfo(String str1, Drawable drawable) {
            m_fieldStr = str1;
            m_value = -1;
            m_drawable = drawable;
        }

        public String toString() {
            return m_fieldStr;
        }

        public String fieldStr() {
            return m_fieldStr;
        }

        public boolean hasValue() {
            return m_value != -1;
        }

        public int getValue() {
            return m_value;
        }

        public Drawable getDrawable() {
            if (Build.VERSION.SDK_INT >= 21) {
                return hasValue() ? getResources().getDrawable(getValue(), getContext().getTheme()) : m_drawable;
            } else {
                return hasValue() ? getResources().getDrawable(getValue()) : m_drawable;
            }
        }
    }

    private class IconArrayAdapter extends ArrayAdapter<IconInfo> {

        public IconArrayAdapter(Context context, int rowLayoutId, int textViewResourceId, List<IconInfo> objects) {
            super(context, rowLayoutId, textViewResourceId, objects);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = super.getView(position, convertView, parent);

            TextView imageInfo = Ui.viewById(view, R.id.iconInfo);

            IconInfo iconInfo = getItem(position);
            Drawable iconD = iconInfo.getDrawable();
            if (iconD != null) {
                String className = iconD.getClass().getSimpleName();
                String infoStr = String.format(Locale.getDefault(), "%d x %d (%c)", iconD.getIntrinsicWidth(),
                        iconD.getIntrinsicHeight(), className.charAt(0));

                // infoStr = infoStr + " " + className;
                // NinePatchDrawable ninePatch = (NinePatchDrawable)iconD;
                imageInfo.setText(infoStr);
            }

            ImageView imageView = Ui.viewById(view, R.id.iconImage1);
            imageView.setImageDrawable(iconD);
            imageView = Ui.viewById(view, R.id.iconImage2);
            imageView.setImageDrawable(iconD);
            imageView = Ui.viewById(view, R.id.iconImage3);
            imageView.setImageDrawable(iconD);
            imageView = Ui.viewById(view, R.id.iconImage4);
            imageView.setImageDrawable(iconD);

            if ((position & 1) == 1)
                view.setBackgroundColor(m_backgroundColor);
            else
                view.setBackgroundColor(m_alternateColor);

            return view;
        }

    }

    /**
     * Show a 'StateListDrawable' information
     *
     * @param imageView
     * @param row1
     * @param row2
     * @param stateListDrawable
     * @param state
     * @param desc
     * @param stateIcons
     */
    private void showStateIcon(final ImageView imageView, TableRow row1, TableRow row2,
            StateListDrawable stateListDrawable, int state, String desc, Set<Drawable> stateIcons) {

        stateListDrawable.setState(new int[] { state });
        Drawable stateD = stateListDrawable.getCurrent();
        if (stateD != null && !stateIcons.contains(stateD)) {
            stateIcons.add(stateD);
            ImageButton stateImageView = new ImageButton(imageView.getContext());
            Drawable[] drawables = new Drawable[] { stateD,
                    getResources().getDrawable(R.drawable.button_border_sel) };

            LayerDrawable layerDrawable = new LayerDrawable(drawables);
            stateImageView.setImageDrawable(layerDrawable);
            //   stateImageView.setBackgroundResource(R.drawable.button_border_sel);
            stateImageView.setPadding(10, 10, 10, 10);
            stateImageView.setMinimumHeight(8);
            stateImageView.setMinimumWidth(8);
            stateImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    imageView.setImageDrawable(((ImageView) v).getDrawable());
                }
            });

            TextView stateTextView = new TextView(imageView.getContext());
            stateTextView.setText(desc);
            stateTextView.setTextSize(12);
            stateTextView.setGravity(Gravity.CENTER);

            row1.addView(stateTextView);
            row2.addView(stateImageView);
        }
    }

    /**
     * Show a 'LayerDrawable'  information.
     *
     * @param imageView
     * @param row1
     * @param row2
     * @param iconD
     * @param layerIdx
     */
    private void showLayerIcon(final ImageView imageView, TableRow row1, TableRow row2, Drawable iconD,
            int layerIdx) {

        if (iconD != null) {
            ImageView layerImageView = new ImageView(imageView.getContext());

            layerImageView.setImageDrawable(iconD);
            layerImageView.setPadding(10, 10, 10, 10);
            layerImageView.setMinimumHeight(8);
            layerImageView.setMinimumWidth(8);
            layerImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    imageView.setImageDrawable(((ImageView) v).getDrawable());
                }
            });

            TextView stateTextView = new TextView(imageView.getContext());
            stateTextView.setText(String.valueOf(layerIdx));
            stateTextView.setTextSize(12);
            stateTextView.setGravity(Gravity.CENTER);

            row1.addView(stateTextView);
            row2.addView(layerImageView);
        }
    }

    /**
     * Show 'AnimationDrawable'  information
     *
     * @param imageView
     * @param animationDrawable
     * @param row1
     * @param row2
     */
    private void showAnimationBtns(final ImageView imageView, final AnimationDrawable animationDrawable,
            TableRow row1, TableRow row2) {

        int[] imageResIds = new int[] { android.R.drawable.ic_media_pause, android.R.drawable.ic_media_play
                // , android.R.drawable.ic_media_next
        };

        String[] descBtns = new String[] { "Pause", "Play"
                // , "Next"
        };

        ImageButton btnImage;
        TextView btnDesc;

        for (int idx = 0; idx < imageResIds.length; idx++) {

            btnImage = new ImageButton(imageView.getContext());
            btnImage.setTag(Integer.valueOf(idx));

            btnImage.setImageResource(imageResIds[idx]);
            btnImage.setPadding(10, 10, 10, 10);
            btnImage.setMinimumHeight(8);
            btnImage.setMinimumWidth(8);
            btnImage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int n = (Integer) v.getTag();
                    switch (n) {
                    case 0: // pause
                        animationDrawable.stop();
                        break;
                    case 1: // play
                        animationDrawable.stop();
                        animationDrawable.start();
                        break;
                    case 2: // next
                        break;
                    }

                }
            });

            row1.addView(btnImage);

            btnDesc = new TextView(imageView.getContext());
            btnDesc.setText(descBtns[idx]);
            btnDesc.setTextSize(12);
            btnDesc.setGravity(Gravity.CENTER);
            row2.addView(btnDesc);
        }

        // Can't start now - icon not fully rendered, see onChangeFocus
        // animationDrawable.stop();
        // animationDrawable.start();

    }

    /**
     * Display icon (drawable) information
     *
     * @param iconInfo
     */
    private void showIconDialog(IconInfo iconInfo) {
        Drawable iconD = iconInfo.getDrawable();
        String iconType = iconD.getClass().getSimpleName();

        LayoutInflater inflater = m_context.getLayoutInflater();
        final View dialogLayout = inflater.inflate(R.layout.icon_dlg, null);

        View shareBtn = dialogLayout.findViewById(R.id.icon_dlg_share);
        shareBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Utils.shareScreen(dialogLayout, "iconDetail", null);
            }
        });

        final TextView imageName = Ui.viewById(dialogLayout, R.id.icon_dlg_name);
        final TextView imageSize = Ui.viewById(dialogLayout, R.id.icon_dlg_size);
        final TextView imageType = Ui.viewById(dialogLayout, R.id.icon_dlg_type);
        final TextView imageExtra = Ui.viewById(dialogLayout, R.id.icon_dlg_extra);

        imageName.setText(iconInfo.fieldStr());
        imageSize.setText(String.format("Size: %d x %d", iconD.getIntrinsicWidth(), iconD.getIntrinsicHeight()));
        imageType.setText(iconType);

        final ImageView imageView = Ui.viewById(dialogLayout, R.id.icon_dlg_image);
        // imageView.setImageDrawable(iconD);
        boolean hasStates = iconD.isStateful();

        final View stateTitle = dialogLayout.findViewById(R.id.icon_dlg_state_title);
        stateTitle.setVisibility(hasStates ? View.VISIBLE : View.GONE);

        final TableRow row1 = Ui.viewById(dialogLayout, R.id.icon_dlg_state_row1);
        row1.removeAllViews();

        final TableRow row2 = Ui.viewById(dialogLayout, R.id.icon_dlg_state_row2);
        row2.removeAllViews();

        boolean showRows = false;
        String extraInfo = "";

        if (hasStates) {
            extraInfo = "StateFul";
            showRows = true;

            StateListDrawable stateListDrawable = (StateListDrawable) iconD;
            Set<Drawable> stateIcons = new HashSet<Drawable>();
            showStateIcon(imageView, row1, row2, stateListDrawable, android.R.attr.state_enabled, "Enabled",
                    stateIcons);
            showStateIcon(imageView, row1, row2, stateListDrawable, android.R.attr.state_pressed, "Pressed",
                    stateIcons);
            showStateIcon(imageView, row1, row2, stateListDrawable, android.R.attr.state_checked, "Checked",
                    stateIcons);
            showStateIcon(imageView, row1, row2, stateListDrawable, android.R.attr.state_selected, "Selected",
                    stateIcons);
        }

        if (iconType.equals(LayerDrawable.class.getSimpleName())) {
            showRows = true;
            LayerDrawable layerDrawable = (LayerDrawable) iconD;
            int layerCnt = layerDrawable.getNumberOfLayers();
            extraInfo = String.format(Locale.getDefault(), "Layers:%d", layerCnt);
            for (int layerIdx = 0; layerIdx < Math.min(layerCnt, 3); layerIdx++) {
                showLayerIcon(imageView, row1, row2, layerDrawable.getDrawable(layerIdx), layerIdx);
            }
        } else if (iconType.equals(AnimationDrawable.class.getSimpleName())) {
            final AnimationDrawable animationDrawable = (AnimationDrawable) iconD;
            extraInfo = String.format(Locale.getDefault(), "Frames:%d", animationDrawable.getNumberOfFrames());
            showRows = true;
            showAnimationBtns(imageView, animationDrawable, row1, row2);

            // Can't control animation at this time, drawable not rendered yet.
            // animationDrawable.stop();
        }

        row1.setVisibility(showRows ? View.VISIBLE : View.GONE);
        row2.setVisibility(showRows ? View.VISIBLE : View.GONE);

        imageExtra.setText(extraInfo);
        imageView.setImageDrawable(iconD);

        dialogLayout.findViewById(R.id.icon_dlg_whiteBtn).setOnClickListener(new View.OnClickListener() {
            @SuppressWarnings("deprecation")
            @Override
            public void onClick(View v) {
                imageView.setBackgroundDrawable(v.getBackground());
            }
        });

        dialogLayout.findViewById(R.id.icon_dlg_grayBtn).setOnClickListener(new View.OnClickListener() {
            @SuppressWarnings("deprecation")
            @Override
            public void onClick(View v) {
                imageView.setBackgroundDrawable(v.getBackground());
            }
        });

        dialogLayout.findViewById(R.id.icon_dlg_blackBtn).setOnClickListener(new View.OnClickListener() {
            @SuppressWarnings("deprecation")
            @Override
            public void onClick(View v) {
                imageView.setBackgroundDrawable(v.getBackground());
            }
        });

        dialogLayout.findViewById(R.id.icon_dlg_squaresBtn).setOnClickListener(new View.OnClickListener() {
            @SuppressWarnings("deprecation")
            @Override
            public void onClick(View v) {
                imageView.setBackgroundDrawable(v.getBackground());
            }
        });

        AlertDialog.Builder builder = new AlertDialog.Builder(m_context);
        builder.setView(dialogLayout);

        builder.setMessage("Icon").setCancelable(false).setPositiveButton("Close",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // if this button is clicked, close
                        dialog.cancel();
                    }
                });

        builder.show();
    }
}