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.
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.
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.
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);
}
}
}
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);
}