A dialog above all the activities

Apr 19 2012

If you want to show a dialog in the context of the whole application like this:

AlertDialog newDialog = new AlertDialog.Builder(getApplicationContext())
                .setMessage("Hello").setPositiveButton("OK", null).setCancelable(true).create();

You’ll get following runtime error:

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

You need to set this dialog as a system dialog like this:

newDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

And you need following permission:


The dialog will be displayed above all the activity in your application, useful when you need to notify user across the activities, e.g. login token is expired.

No responses yet

Sort algorithm visualization

Jan 30 2012

As a busy coder, I almost forget all the data structure, algorithm learnt at school, because I don’t use them at work basically. However, when you got a job interview, they are your essential weapon need to be armed.

And here’s a simple android app to help you make a little bit fun with sort algorithm.

        Algorithm Fight

1, Introduction

Simple app to visualize sort algorithm. You can select two algorithm to “fight” with each other and check who finish sorting first. And there’s details about the algorithms, you can check out for it at any time.

Download Now for FREE!

2, Features and Screenshots

Fighting

 

Winner & Looser

 

Algorithm currently implemented

 

Algorithm details

 

 

Several settings to make more fun

 

 

3, Language support:

English, Chinese

 

4, Reference:

No responses yet

Create custom dialogs

Jan 18 2012

Don’t like android system dialog style? You want to change it. However, the commonly used AlertDialog doesn’t allow you change the title bar, change the background, change the button style… We need to inherit Dialog class to make everything by ourselves.

 

Common alert dialog:

public class CommonDialog extends Dialog {

    // UI
    private TextView mTitleTextView;

    private ImageView mTitleIcon;

    private Button mButton1;

    private Button mButton2;

    private Button mButton3;

    private View mButtonBar;

    private View mLeftSpacer;

    private View mRightSpacer;

    private LinearLayout mContentViewContainer;

    private View mCustomContentView;

    private TextView mMessageTextView;

    // Data
    private CharSequence mTitleText;

    private CharSequence mDialogMessage;

    private int mTitleIconResource;

    private CharSequence mButton1Text;

    private CharSequence mButton2Text;

    private CharSequence mButton3Text;

    private DialogInterface.OnClickListener mButton1OnClickListner;

    private DialogInterface.OnClickListener mButton2OnClickListner;

    private DialogInterface.OnClickListener mButton3OnClickListner;

    // Flag to decide if the dialog has been displayed.
    private boolean mHasDisplayed;

    private View.OnClickListener mOnButtonClickListener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            boolean bottomBtnClicked = false;
            int which = 0;

            switch (v.getId()) {
                case R.id.btn_common_dlg_button1:
                    bottomBtnClicked = true;
                    which = DialogInterface.BUTTON_POSITIVE;
                    break;
                case R.id.btn_common_dlg_button2:
                    bottomBtnClicked = true;
                    which = DialogInterface.BUTTON_NEGATIVE;
                    break;
                case R.id.btn_common_dlg_button3:
                    bottomBtnClicked = true;
                    which = DialogInterface.BUTTON_NEUTRAL;
                    break;
            }

            if (bottomBtnClicked) {
                if (mButton1OnClickListner != null && which == DialogInterface.BUTTON_POSITIVE) {
                    mButton1OnClickListner.onClick(CommonDialog.this, which);
                }
                if (mButton2OnClickListner != null && which == DialogInterface.BUTTON_NEGATIVE) {
                    mButton2OnClickListner.onClick(CommonDialog.this, which);
                }
                if (mButton3OnClickListner != null && which == DialogInterface.BUTTON_NEUTRAL) {
                    mButton3OnClickListner.onClick(CommonDialog.this, which);
                }
            }
        }
    };

    public CommonDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    public CommonDialog(Context context, int theme) {
        super(context, theme);
    }

    public CommonDialog(Context context) {
        super(context, R.style.CustomDialog);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.common_dialog);

        // Title bar
        mTitleTextView = (TextView)findViewById(R.id.tv_common_dlg_title);
        if (!TextUtils.isEmpty(mTitleText)) {
            mTitleTextView.setText(mTitleText);
        }

        mTitleIcon = (ImageView)findViewById(R.id.iv_common_dlg_title_icon);
        if (mTitleIconResource > 0) {
            mTitleIcon.setImageResource(mTitleIconResource);
        }

        // Buttons
        mButton1 = (Button)findViewById(R.id.btn_common_dlg_button1);

        if (!TextUtils.isEmpty(mButton1Text)) {
            mButton1.setText(mButton1Text);
        }

        mButton1.setOnClickListener(mOnButtonClickListener);

        mButton2 = (Button)findViewById(R.id.btn_common_dlg_button2);

        if (!TextUtils.isEmpty(mButton2Text)) {
            mButton2.setText(mButton2Text);
        }

        mButton2.setOnClickListener(mOnButtonClickListener);

        mButton3 = (Button)findViewById(R.id.btn_common_dlg_button3);

        if (!TextUtils.isEmpty(mButton3Text)) {
            mButton3.setText(mButton3Text);
        }

        mButton3.setOnClickListener(mOnButtonClickListener);

        mLeftSpacer = findViewById(R.id.ll_common_dlg_left_spacer);
        mRightSpacer = findViewById(R.id.ll_common_dlg_right_spacer);

        // Button bar
        mButtonBar = findViewById(R.id.ll_common_dlg_button_bar);

        // Content
        mContentViewContainer = (LinearLayout)findViewById(R.id.ll_common_dlg_content);

        if (mCustomContentView != null) {
            mContentViewContainer.addView(mCustomContentView);
        }

        // Text view
        mMessageTextView = (TextView)mContentViewContainer
                .findViewById(R.id.tv_common_dialog_message);

        if(!TextUtils.isEmpty(mDialogMessage)){
            mMessageTextView.setText(mDialogMessage);
        }

        mHasDisplayed = true;

        updateViews();
    }

    /**
     * Add your custom view into the dialog.
     *
     * @param contentView your custom view
     */
    public void insertContentView(View contentView) {

        mCustomContentView = contentView;

        if (mContentViewContainer != null) {
            mContentViewContainer.removeAllViews();

            LayoutParams layoutParams = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            mContentViewContainer.addView(contentView, layoutParams);
        }
    }

    private void updateViews() {

        if (mHasDisplayed) {

            boolean hasButton = updateButtons();

            if (hasButton) {
                mContentViewContainer.setBackgroundResource(R.drawable.bg_dialog_content);
                mButtonBar.setVisibility(View.VISIBLE);
            } else {
                mContentViewContainer.setBackgroundResource(R.drawable.bg_dialog_bottom_bar_no_button);
                mButtonBar.setVisibility(View.GONE);
            }
        }
    }

    private boolean updateButtons() {
        int BIT_BUTTON_1 = 1;
        int BIT_BUTTON_2 = 2;
        int BIT_BUTTON_3 = 4;

        int whichButtons = 0;

        if (TextUtils.isEmpty(mButton1.getText())) {
            mButton1.setVisibility(View.GONE);
            mButton1.setOnClickListener(null);
        } else {
            mButton1.setVisibility(View.VISIBLE);

            whichButtons = whichButtons | BIT_BUTTON_1;
        }

        if (TextUtils.isEmpty(mButton2.getText())) {
            mButton2.setVisibility(View.GONE);
            mButton2.setOnClickListener(null);
        } else {
            mButton2.setVisibility(View.VISIBLE);

            whichButtons = whichButtons | BIT_BUTTON_2;
        }

        if (TextUtils.isEmpty(mButton3.getText())) {
            mButton3.setVisibility(View.GONE);
            mButton3.setOnClickListener(null);
        } else {
            mButton3.setVisibility(View.VISIBLE);

            whichButtons = whichButtons | BIT_BUTTON_3;
        }

        if (whichButtons == BIT_BUTTON_1) {
            centerButton(mButton1);
        } else if (whichButtons == BIT_BUTTON_2) {
            centerButton(mButton2);
        } else if (whichButtons == BIT_BUTTON_3) {
            centerButton(mButton3);
        } else {
            mLeftSpacer.setVisibility(View.GONE);
            mRightSpacer.setVisibility(View.GONE);
        }

        return whichButtons != 0;
    }

    /**
     * Set title text.
     */
    @Override
    public void setTitle(CharSequence title) {
        mTitleText = title;

        if (mTitleTextView != null) {
            mTitleTextView.setText(title);
        }
    }

    /**
     * Set title text.
     */
    public void setTitleIconResource(int titleIconRes) {
        mTitleIconResource = titleIconRes;

        if (mTitleIcon != null) {
            mTitleIcon.setImageResource(titleIconRes);
        }
    }

    /**
     * Set left button.
     */
    public void setPositiveButton(CharSequence text, DialogInterface.OnClickListener onClickListener) {
        mButton1Text = text;
        mButton1OnClickListner = onClickListener;

        if (mButton1 != null) {
            mButton1.setText(text);
            mButton1.setOnClickListener(mOnButtonClickListener);
        }
    }

    /**
     * Set left button.
     */
    public void setPositiveButton(int textRes, DialogInterface.OnClickListener onClickListener) {
        setPositiveButton(getContext().getText(textRes), onClickListener);
    }

    /**
     * Set right button.
     */
    public void setNegativeButton(CharSequence text, DialogInterface.OnClickListener onClickListener) {
        mButton2Text = text;
        mButton2OnClickListner = onClickListener;

        if (mButton2 != null) {
            mButton2.setText(text);
            mButton2.setOnClickListener(mOnButtonClickListener);
        }
    }

    /**
     * Set right button.
     */
    public void setNegativeButton(int textRes, DialogInterface.OnClickListener onClickListener) {
        setNegativeButton(getContext().getText(textRes), onClickListener);
    }

    /**
     * Set middle button.
     */
    public void setNeutralButton(CharSequence text, DialogInterface.OnClickListener onClickListener) {
        mButton3Text = text;
        mButton3OnClickListner = onClickListener;

        if (mButton3 != null) {
            mButton3.setText(text);
            mButton3.setOnClickListener(mOnButtonClickListener);
        }
    }

    /**
     * Set middle button.
     */
    public void setNeutralButton(int textRes, DialogInterface.OnClickListener onClickListener) {
        setNeutralButton(getContext().getText(textRes), onClickListener);
    }

    private void centerButton(Button button) {

        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)button.getLayoutParams();

        params.gravity = Gravity.CENTER_HORIZONTAL;
        params.weight = 0.5f;

        button.setLayoutParams(params);

        mLeftSpacer.setVisibility(View.VISIBLE);
        mRightSpacer.setVisibility(View.VISIBLE);
    }

    /**
     * Create alert dialog with OK button.
     */
    public static CommonDialog createAlertMessageDialog(Context context,
            CharSequence titleText, CharSequence messageText) {
        CommonDialog dlg = new CommonDialog(context);

        setupCommonMessageDialog(context, titleText, messageText, dlg);

        dlg.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }

        });

        return dlg;
    }

    protected static void setupCommonMessageDialog(Context context, CharSequence titleText,
            CharSequence messageText, final CommonDialog dialog) {
        dialog.setTitle(titleText);

        LayoutInflater inflater = (LayoutInflater)context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View messageView = inflater.inflate(R.layout.common_dialog_message_view, null);

        TextView msgTextView = (TextView)messageView
                .findViewById(R.id.tv_common_dialog_message);
        msgTextView.setText(messageText);

        dialog.insertContentView(messageView);
    }

    /**
     * Create alert dialog with OK button.
     */
    public static CommonDialog createAlertMessageDialog(Context context, int titleTextRes,
            int messageTextRes) {
        return createAlertMessageDialog(context, context.getString(titleTextRes), context
                .getString(messageTextRes));
    }

    /**
     * Create confirm dialog with OK and CANCEL button.
     */
    public static CommonDialog createConfirmDialog(Context context, CharSequence titleText,
            CharSequence messageText) {

        final CommonDialog dialog = new CommonDialog(context);

        setupCommonMessageDialog(context, titleText, messageText, dialog);

        dialog.setPositiveButton(R.string.ok, null);
        dialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }

        });

        return dialog;
    }

    /**
     * Create confirm dialog with OK and CANCEL button.
     */
    public static CommonDialog createConfirmDialog(Context context, int titleTextRes,
            int messageTextRes) {
        return createConfirmDialog(context, context.getString(titleTextRes), context
                .getString(messageTextRes));
    }

    public void setDialogMessage(int messageTextRes){
        setDialogMessage(getContext().getString(messageTextRes));
    }

    /**
     * Update the dialog message.
     *
     * Only for simple alert dialog and confirm dialog.
     * You must call createAlertMessage or createConfirmDialog first.
     *
     * @param messageText
     */
    public void setDialogMessage(CharSequence messageText) {
        mDialogMessage = messageText;

        if (mMessageTextView != null) {
            mMessageTextView.setText(messageText);
        }
    }
}

Let’s custom our dialog view:



    
        
        
    

    
    

    

        
            
            

And here’s the custom linear layout:

public class WeightedLinearLayout extends LinearLayout {

    private static final float DEFAULT_PORTRAIT_WIDTH_WEIGHT = 0.9f;

    private static final float DEFAULT_LANDSCAPE_WIDTH_WEIGHT = 0.9f;

    private static final float DEFAULT_PORTRAIT_HEIGHT_MIN_WEIGHT = 0.375f;

    private static final float DEFAULT_PORTRAIT_HEIGHT_MAX_WEIGHT = 0.725f;

    private static final float DEFAULT_LANDSCAPE_HEIGHT_MIN_WEIGHT = 0.375f;

    private static final float DEFAULT_LANDSCAPE_HEIGHT_MAX_WEIGHT = 0.725f;

    private float mPortraitWidthWeight;

    private float mLandscapeWidthWeight;

    private float mPortraitHeightMinWeight;

    private float mPortraitHeightMaxWeight;

    private float mLandscapeHeightMinWeight;

    private float mLandscapeHeightMaxWeight;

    public WeightedLinearLayout(Context context) {
        super(context);
    }

    public WeightedLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WeightedLinearLayout);

        mPortraitWidthWeight = a.getFloat(R.styleable.WeightedLinearLayout_portraitWidthWeight, DEFAULT_PORTRAIT_WIDTH_WEIGHT);
        mLandscapeWidthWeight = a.getFloat(R.styleable.WeightedLinearLayout_landscapeWidthWeight, DEFAULT_LANDSCAPE_WIDTH_WEIGHT);
        mPortraitHeightMinWeight = a.getFloat(R.styleable.WeightedLinearLayout_portraitHeightMinWeight, DEFAULT_PORTRAIT_HEIGHT_MIN_WEIGHT);
        mPortraitHeightMaxWeight = a.getFloat(R.styleable.WeightedLinearLayout_portraitHeightMaxWeight, DEFAULT_PORTRAIT_HEIGHT_MAX_WEIGHT);
        mLandscapeHeightMinWeight = a.getFloat(R.styleable.WeightedLinearLayout_landscapeHeightMinWeight, DEFAULT_LANDSCAPE_HEIGHT_MIN_WEIGHT);
        mLandscapeHeightMaxWeight = a.getFloat(R.styleable.WeightedLinearLayout_landscapeHeightMaxWeight, DEFAULT_LANDSCAPE_HEIGHT_MAX_WEIGHT);

        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
        int screenWidth = metrics.widthPixels;
        int screenHeight = metrics.heightPixels;

        boolean isPortrait = screenWidth < screenHeight;

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        boolean measure = false;

        widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        float widthWeight = isPortrait ? mPortraitWidthWeight : mLandscapeWidthWeight;
        if (widthMode == MeasureSpec.AT_MOST && widthWeight > 0.0f) {
            //if (width < (screenWidth * widthWeight)) {
                widthMeasureSpec = MeasureSpec.makeMeasureSpec((int)(screenWidth * widthWeight),
                        MeasureSpec.EXACTLY);
                measure = true;
            //}
        }

        float minHeight = isPortrait ? mPortraitHeightMinWeight : mLandscapeHeightMinWeight;
        float maxHeight = isPortrait ? mPortraitHeightMaxWeight : mLandscapeHeightMaxWeight;

        if(heightMode == MeasureSpec.AT_MOST) {
            if(minHeight > 0.0f && height < (screenHeight * minHeight)){
                heightMeasureSpec = MeasureSpec.makeMeasureSpec((int)(screenHeight * minHeight),
                        MeasureSpec.EXACTLY);
                measure = true;
            } else if(maxHeight > 0.0f && height > (screenHeight * maxHeight)){
                heightMeasureSpec = MeasureSpec.makeMeasureSpec((int)(screenHeight * maxHeight),
                        MeasureSpec.EXACTLY);
                measure = true;
            }
        }

        if (measure) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    public void setPortraitHeightMinWeight(float portraitHeightMinWeight) {
        this.mPortraitHeightMinWeight = portraitHeightMinWeight;
    }

    public void setLandscapeHeightMinWeight(float landscapeHeightMinWeight) {
        this.mLandscapeHeightMinWeight = landscapeHeightMinWeight;
    }
}

Now, let’s do some extension, create input dialog based on the common dialog:

public class CommonInputDialog extends CommonDialog {

    protected EditText mEditText;

    public CommonInputDialog(Context context) {
        super(context);

        initEditTextView();
    }

    private void initEditTextView() {

        LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);

        LinearLayout editContainer = (LinearLayout)inflater.inflate(R.layout.common_dialog_edit_text, null);
        editContainer.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        mEditText = (EditText) editContainer.findViewById(R.id.et_common_dialog);

        insertContentView(editContainer);
    }

    public String getInputText(){
        return mEditText.getText().toString();
    }

    public void setInputText(String text) {
        mEditText.setText(text);
    }

    public EditText getEditTextView() {
        return mEditText;
    }

    public void setError(String errText, Drawable indicatorError) {
        mEditText.setError(errText, indicatorError);
    }

    public static CommonInputDialog createSimpleInputDialog(Context context, String title){

        CommonInputDialog inputDialog = new CommonInputDialog(context);

        inputDialog.setTitle(title);

        inputDialog.setPositiveButton(R.string.ok, null);
        inputDialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }

        });

        return inputDialog;
    }

    public static CommonInputDialog createSimpleInputDialog(Context context, int titleRes){
        return createSimpleInputDialog(context, context.getString(titleRes));
    }

}

And a simple list dialog:

public class CommonListDialog extends CommonDialog {

    protected ListView mListView;

    protected TextView mEmptyListTextView;

    protected String mEmptyListText;

    public CommonListDialog(Context context) {
        super(context);

        initListView();

        FrameLayout listViewContainer = new FrameLayout(getContext());
        listViewContainer.setLayoutParams(new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        listViewContainer.addView(mListView, new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View emptyViewContainer = inflater.inflate(R.layout.common_dialog_message_view, null);
        mEmptyListTextView = (TextView)emptyViewContainer.findViewById(R.id.tv_common_dialog_message);

        listViewContainer.addView(emptyViewContainer, new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        mListView.setEmptyView(emptyViewContainer);

        insertContentView(listViewContainer);
    }

    public void setEmptyListText(String emptyText) {
        mEmptyListText = emptyText;

        if (mEmptyListTextView != null && !TextUtils.isEmpty(mEmptyListText)) {
            mEmptyListTextView.setText(mEmptyListText);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (mEmptyListTextView != null && !TextUtils.isEmpty(mEmptyListText)) {
            mEmptyListTextView.setText(mEmptyListText);
        }

        if (mListView.getCount() > 0) {
            WeightedLinearLayout dlgContainer = (WeightedLinearLayout)findViewById(R.id.ll_common_dlg_container);

            dlgContainer.setPortraitHeightMinWeight(0);
            dlgContainer.setLandscapeHeightMinWeight(0);
        }
    }

    protected void initListView() {
        mListView = new ListView(getContext());

        LayoutParams layoutParams = new ListView.LayoutParams(LayoutParams.FILL_PARENT,
                LayoutParams.WRAP_CONTENT);

        mListView.setLayoutParams(layoutParams);
        mListView.setCacheColorHint(0);
        mListView.setDividerHeight(1);
    }

    /**
     * Set adapter to the list.
     *
     * @param adapter
     */
    public void setListAdapter(ListAdapter adapter) {
        if (mListView != null) {
            mListView.setAdapter(adapter);
        }
    }

    /**
     * Set listener for click on the list view.
     *
     * @param onItemClickListener
     */
    public void setOnListItemClickListener(OnItemClickListener onItemClickListener) {
        if (mListView != null) {
            mListView.setOnItemClickListener(onItemClickListener);
        }
    }

    public ListView getListView() {
        return mListView;
    }

    /**
     * Create a simple list dialog.
     *
     * @param context
     * @param title
     * @param listEntries
     * @return
     */
    public static CommonListDialog createSimpleListDialog(Context context, String title,
            String[] listEntries) {
        CommonListDialog listDialog = new CommonListDialog(context);

        listDialog.setTitle(title);
        ArrayAdapter adapter = new ArrayAdapter(context,
                R.layout.simple_dialog_listview_item, R.id.tv_list_text, listEntries);
        listDialog.setListAdapter(adapter);

        return listDialog;
    }

    /**
     * Create a simple list dialog.
     *
     * @param context
     * @param titleRes
     * @param listEntries
     * @return
     */
    public static CommonListDialog createSimpleListDialog(Context context, int titleRes,
            String[] listEntries) {
        return createSimpleListDialog(context, context.getString(titleRes), listEntries);
    }

    /**
     * Create a simple list dialog with header.
     *
     * @param context
     * @param title
     * @param listEntries
     * @param headerText
     * @return
     */
    public static CommonListDialog createSimpleListDialogWithHeader(Context context,
            String title, String[] listEntries, String headerText) {
        CommonListDialog listDialog = new CommonListDialog(context);

        ListView listView = listDialog.getListView();

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View headerView = inflater.inflate(R.layout.list_header_in_dialog, null);

        TextView textView = (TextView)headerView.findViewById(R.id.tv_list_header_in_dialog);
        textView.setText(headerText);

        listView.addHeaderView(headerView);

        listDialog.setTitle(title);

        ArrayAdapter adapter = new ArrayAdapter(context,
                R.layout.simple_dialog_listview_item, R.id.tv_list_text, listEntries);
        listDialog.setListAdapter(adapter);

        return listDialog;
    }

    /**
     * Create a simple list dialog with header.
     *
     * @param context
     * @param titleRes
     * @param listEntries
     * @param headerTextRes
     * @return
     */
    public static CommonListDialog createSimpleListDialogWithHeader(Context context, int titleRes,
            String[] listEntries, int headerTextRes) {
        return createSimpleListDialogWithHeader(context, context.getString(titleRes),
                listEntries, context.getString(headerTextRes));
    }
}

And now, you can create other dialogs easily!

No responses yet

Highlight text in TextView

Jan 18 2012

private BackgroundColorSpan mHighlightBackground = new BackgroundColorSpan(0xFFFFFF00);

private void setTextHighlight(TextView myTextView, String text, int start, int end)
    myTextView.setText(text, BufferType.SPANNABLE);
    Spannable span = (Spannable)myTextView.getText();
    span.setSpan(mHighlightBackground, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

No responses yet

Start animation drawable in onWindowFocusChanged method

Jan 18 2012

Animation drawable:




    

    

    


 

ImageView in layout:


 

Start animation in code:

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        if(hasFocus && !mProgressAnimationStarted) {

            AnimationDrawable progressAnimation = (AnimationDrawable) mProgressImageView.getBackground();
            progressAnimation.start();

            mProgressAnimationStarted = true;
        }
    }

    private void stopAnimation() {
        AnimationDrawable progressAnimation = (AnimationDrawable) mProgressImageView.getBackground();
        progressAnimation.stop();
    }

No responses yet

Hyper link style button

Jan 18 2012

 



服务条款

No responses yet

Custom ViewFlipper to send flipper-ed event

Jan 18 2012

Overwrite setDisplayedChild method.

public class MyViewFlipper extends ViewFlipper {

    private static final String TAG = MomoViewFlipper.class.getSimpleName();

    private OnFlipperChangedListener mOnFlipperChangedListener;

    public interface OnFlipperChangedListener {
        public void onFlipperChanged(int which);
    }

    public MyViewFlipper(Context context) {
        super(context);
    }

    public MyViewFlipper(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setOnFlipperChangedListener(OnFlipperChangedListener onFlipperChangedListener) {
        mOnFlipperChangedListener = onFlipperChangedListener;
    }

    @Override
    public void setDisplayedChild(int whichChild) {
        super.setDisplayedChild(whichChild);

        if (mOnFlipperChangedListener != null) {
            mOnFlipperChangedListener.onFlipperChanged(whichChild);
        }
    }

}

No responses yet

Toggle full screen in code

Jan 18 2012

    private void toggleFullScreen(boolean fullscreen){
        if(fullscreen){
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        }else{
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }

        // Refresh content view
        mContentView.requestLayout();
    }

No responses yet

Simple voice search

Jan 18 2012

It’s easy to integrate Google void search into your application.

    private void onVoiceSearchButtonClicked() {

        Intent voiceSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

        voiceSearchIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);

        // Check http://developer.android.com/reference/android/speech/RecognizerIntent.html for details
        // voiceSearchIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);
        // voiceSearchIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
        // voiceSearchIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, maxResults);
        // voiceSearchIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, pending);
        // voiceSearchIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE, queryExtras);

        try {
            startActivityForResult(voiceSearchIntent, REQUEST_CODE_VOICE_SEARCH);
        } catch (Exception e) {
            Log.e(TAG, "Your phone has no voice search", e);
            Toast.makeText(this, R.string.no_voice_search, Toast.LENGTH_LONG).show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE_VOICE_SEARCH && resultCode == RESULT_OK) {
            ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            if (matches != null && matches.size() > 0) {
                // Start to query in your app
                mQueryEditView.setText(matches.get(0));
            }
        }
    }

Check Android Document for details.

No responses yet

Flick and slug when requery DB in a list

Jan 18 2012

Sometimes you need to requery DB for some special feature for your list view. If you have huge data set, the list view will be flicking and sluggish. And you need to hack on the CursorAdapter.

public class YourCursorAdapter extends CursorAdapter {
    private boolean mLoading = true;

    @Override
    protected void onContentChanged() {
        // Use AsyncQueryHandler to query in a separate thread
    }

    @Override
    public boolean isEmpty() {
        if (getCursor() == null || mLoading) {
            // We don't want the empty state to show when loading.
            return false;
        } else {
            return super.isEmpty();
        }
    }

    @Override
    public void changeCursor(Cursor cursor) {

        if (cursor != null) {
            setLoading(false);
        }

        if (cursor == null) {
            return;
        }

        super.changeCursor(cursor);
    }

    public void setLoading(boolean loading) {
        mLoading = loading;
    }
}

When requesting AsyncQueryHandler to do a background query:

if (mCursorAdapter != null) {
    mCursorAdapter.setLoading(true);
}

No responses yet

Older »