Dialog、Toast、PopupWindow及Log分析

本文分析Dialog的原理,其用到的设计模式,其各种子类,及在Activity中的使用。Toast、Log跟Dialog一样都有提示的功能,所以放一起分析。

1、Dialog实现了4个接口

1) android.content.DialogInterface

包含几个常量,cancel和dismiss方法,

6个嵌套接口OnCancelListener,OnDismissListener,OnShowListener,OnClickListener,
OnMultiChoiceClickListener,OnKeyListener。
2) android.view.Window.Callback
3) android.view.KeyEvent.Callback
4) android.view.View.OnCreateContextMenuListener

2、AlertDialog实现

new AlertDialog.Builder(this)
	.setTitle("very good")
	.create()//实例化AlertDialog
	.show();
上面AlertDialog的实现用了建造者模式。

AlertDialog、AlertDialog.Builder分别适配了com.android.internal.app.AlertController和AlertController.AlertParams,用了对象的适配器模式。

final String[] items = {"I", "II", "III", "aVR", "aVL", "aVF", "V1", "V2", "V3", "V4", "V5", "V6"};
final SharedPreferences sp = getContext().getApplicationContext().getSharedPreferences("ecg12", Context.MODE_PRIVATE);
DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
	//每次点击列表项将设置值保留
	int mWhich;
	@Override
	public void onClick(DialogInterface dialog, int which) {
		//-1,-2,-3不会和index发生冲突
		if(which==DialogInterface.BUTTON_POSITIVE){
			sp.edit().putInt("ecg12_index", mWhich).apply();
			dialog.dismiss();
		}else{
			mWhich = which;
		}
	}
};
new AlertDialog.Builder(getContext())
	.setSingleChoiceItems(items, sp.getInt("ecg12_index",0), onClickListener)
	.setTitle("寻峰导联设置")
	.setIcon(R.drawable.settings_ecg)
	.setPositiveButton(R.string.confirm, onClickListener).show();

3、Toast

一般通过Toast.makeText(Context context, CharSequence text, int duration).show()来使用Toast。

也可直接实例化使用:

Toast toast = new Toast(MainActivity.this);
TextView tv = new TextView(MainActivity.this);
tv.setText("嘻嘻");
toast.setView(tv);
toast.show();

Toast包含内部类private static class TN extends ITransientNotification.Stub作为其属性,并封装了它的方法。

TN包含Handler属性,Handler实例化需要之前调用Looper.prepare(),否则new Handler()时报异常。


4、Log

Log只含有私有无参构造private Log(),所以禁止直接实例化。

Log.v(String tag, String msg)

Log.e(String tag, String msg, Throwable tr):可打印异常信息
Log.println(int priority, String tag, String msg)

priority区分优先级,用不同颜色显示,如Log.VERBOSE,Log.WARN,Log.ASSERT等。

System.out.println("Good");tag为System.out,level为i,priority为INFO
System.err.println("Bad");tag为System.err,level为w,priority为WARN

5、PopupWindow

TextView textView = new TextView(MainActivity.this);
textView.setText("so long");
mPopupWindow = new PopupWindow(textView, ViewGroup.LayoutParams.WRAP_CONTENT, 
		ViewGroup.LayoutParams.WRAP_CONTENT);
mPopupWindow.showAtLocation((View) v.getParent(), Gravity.BOTTOM, 0, 0);
mPopupWindow.dismiss();
6、比较

Log在LogCat中显示,方便调试时查看,实现过滤、保存、删除。


Toast在指定时间到达后自动消失。

Dialog会挡住当前Activity,PopupWindow不会。

7、示例演示Dialog的各种用法

1)MainActivity.java

public class MainActivity extends FragmentActivity {
	private static final String TAG = MainActivity.class.getSimpleName();
	public static final int DIALOG_ID_TEST = 0x01;
	EditText editText;
	Editable editable;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		editText = new EditText(this);
		editText.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
		editable = Editable.Factory.getInstance().newEditable("WhyWhatHow");
	}
	public void onClick(View v){
		Calendar calendar = Calendar.getInstance();
		switch (v.getId()) {
		case R.id.btn_dialog:
			Bundle bundle = new Bundle();
			bundle.putString("Content", new SimpleDateFormat("yyyy/MM/dd HH-mm-ss E").format(new Date()));
			showDialog(DIALOG_ID_TEST, bundle);break;
		case R.id.btn_char:
			CharacterPickerDialog characterPickerDialog = new CharacterPickerDialog(this, editText, editable, "123456789", false){
				public void onClick(View v) {
					dismiss();
					Log.i(TAG, "onClick-"+editText.getText());
				};
				@Override
				public void onItemClick(AdapterView parent, View view, int position, long id) {
					Log.i(TAG, "onItemClick-"+position);
				};
			};
			characterPickerDialog.show();break;
		case R.id.btn_date:
			int year = calendar.get(Calendar.YEAR);
			int month = calendar.get(Calendar.MONTH);
			int day = calendar.get(Calendar.DAY_OF_MONTH);
			DatePickerDialog dialog = new DatePickerDialog(this, mOnDateSetListener, year, month, day);
			if(android.os.Build.VERSION.SDK_INT>=11){
				dialog.getDatePicker().setCalendarViewShown(false);
				dialog.getDatePicker().setMaxDate(new Date().getTime());
				//1900年1月1号
				dialog.getDatePicker().setMinDate(new Date(0, 0, 1).getTime());
			}
			dialog.show();break;
		case R.id.btn_time:
			int h = calendar.get(Calendar.HOUR_OF_DAY);
			int m = calendar.get(Calendar.MINUTE);
			TimePickerDialog timePickerDialog = new TimePickerDialog(this, mTimeSetListener, h, m, true);
			timePickerDialog.show();break;
		case R.id.btn_progress:
			ProgressDialog progressDialog = new ProgressDialog(this);
			progressDialog.setMax(100);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			progressDialog.show();break;
		case R.id.btn_DialogFragment:
			DialogFragment dialogFragment = MyDialogFragment.getInstance(
				new SimpleDateFormat("yyyy/MM/dd HH-mm-ss E").format(new Date()));
			dialogFragment.show(getSupportFragmentManager(), "fantastic");break;
		case R.id.btn_Activity://Activity作为Dialog使用
			startActivity(new Intent(this, DialogDemo.class));
		default:
			break;
		}
	}
	@Override
	protected Dialog onCreateDialog(int id, Bundle args) {
		//首次showDialog才会触发
		Log.i(TAG, "onCreateDialog");
		switch (id) {
		case DIALOG_ID_TEST:
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("The current time is ...")
				.setMessage("The present");
			return builder.create();

		default:
			break;
		}
		return null;
	}
	@Override
	protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
		//每次showDialog都会触发
		Log.i(TAG, "onPrepareDialog");
		switch (id) {
		case DIALOG_ID_TEST:
			((AlertDialog)dialog).setMessage(args.getString("Content"));
			break;

		default:
			break;
		}
	}
	private DatePickerDialog.OnDateSetListener mOnDateSetListener = new DatePickerDialog.OnDateSetListener() {
		@Override
		public void onDateSet(DatePicker view, int year, int monthOfYear,int dayOfMonth) {
			Log.i(TAG, "onDateSet-"+year+"-"+monthOfYear+"-"+dayOfMonth);
		}
	};
	private TimePickerDialog.OnTimeSetListener mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
		@Override
		public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
			Log.i(TAG, "onTimeSet-"+hourOfDay+"-"+minute);
		}
	};
}
2)activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <Button 
        android:id="@+id/btn_dialog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="dialog"/>
    <Button 
        android:id="@+id/btn_Activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="Activity"/>
    <Button 
        android:id="@+id/btn_date"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="date"/>
    <Button 
        android:id="@+id/btn_time"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="time"/>
    <Button 
        android:id="@+id/btn_char"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="char"/>
    <Button 
        android:id="@+id/btn_progress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="progress"/>
    <Button 
        android:id="@+id/btn_DialogFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="DialogFragment"/>
</LinearLayout>
3)MyDialogFragment.java
/**
 * API level 4(API level 11引入)
 * 高效封装和管理Dialog的lifecycle,和Dialog状态一致
 * override either onCreateDialog or onCreateView
 */
public class MyDialogFragment extends DialogFragment {
	private static final String TAG = MyDialogFragment.class.getSimpleName();
	private static final String CURRENT_TIME = "CURRENT_TIME";
	public static MyDialogFragment getInstance(String currentTime){
		MyDialogFragment fragment = new MyDialogFragment();
		Bundle bundle = new Bundle();
		bundle.putString(CURRENT_TIME, currentTime);
		fragment.setArguments(bundle);
		return fragment;
	}
	@Override
	public Dialog onCreateDialog(Bundle savedInstanceState) {
		Log.i(TAG, "onCreateDialog");
//		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
//		builder.setTitle("The current time is ...")
//			.setMessage(getArguments().getString(CURRENT_TIME));
//		return builder.create();
		Dialog dialog = new MyDialog(getActivity());
		dialog.setTitle("Come on baby!");
		dialog.getWindow().setContentView(R.layout.dialog);
		EditText editText = (EditText) dialog.getWindow().findViewById(R.id.editText);
		editText.setHint("input something");
		return dialog;
	}
//	@Override
//	public View onCreateView(LayoutInflater inflater, ViewGroup container,
//			Bundle savedInstanceState) {
//		View view = inflater.inflate(R.layout.dialog_view, container, false);
//		TextView tv = (TextView) view.findViewById(R.id.dialog_view_text);
//		tv.setText("The girl is my lover!");
//		return view;
//	}
	@Override
	public void onCreate(Bundle savedInstanceState) {
		Log.i(TAG, "onCreate");
		super.onCreate(savedInstanceState);
	}
	@Override
	public void onStart() {
		Log.i(TAG, "onStart");
		super.onStart();
	}
	@Override
	public void onStop() {
		Log.i(TAG, "onStop");
		super.onStop();
	}
	@Override
	public void onDestroy() {
		Log.i(TAG, "onDestroy");
		super.onDestroy();
	}
}
4)MyDialog.java
/**
 * lifecycle of Dialog
 */
public class MyDialog extends Dialog {
	private static final String TAG = MyDialog.class.getSimpleName();
	public MyDialog(Context context) {
		super(context);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Log.i(TAG, "onCreate");
		super.onCreate(savedInstanceState);
	}

	@Override
	protected void onStart() {
		Log.i(TAG, "onStart");
		super.onStart();
	}

	@Override
	protected void onStop() {
		Log.i(TAG, "onStop");
		super.onStop();
	}
}
5)dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <EditText 
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>
6)dialog_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView 
        android:id="@+id/dialog_view_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>
7)DialogDemo.java
/**
 * 作为Dialog使用
 */
public class DialogDemo extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_dialog);
	}
}
8)activity_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView 
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Activity"/>
</LinearLayout>
9)AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.dialogtest3"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.dialogtest3.MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTask" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.example.dialogtest3.DialogDemo"
            android:theme="@android:style/Theme.Dialog"></activity>
    </application>

</manifest>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值