自己写layout,用LayoutInflater进行动态加载,然后用setContentView进行添加。
layout方面,对title还有按键以及对话框整体进行了设置,通过background引用drawable中相应的xml文件实现调整。
//布局文件
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:gravity="center_vertical"
android:layout_height="match_parent"
android:background="@drawable/dialog_background">
"@+id/text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/myTextView"
/>
"@+id/text_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是内容"
android:textAppearance="@android:style/TextAppearance.Medium"
android:layout_gravity="center_horizontal"
android:layout_margin="15dp"/>
"match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
第一个TestView引用了styles中的布局,这种方法通常用来存放比较常用的布局,以便重复使用。
//styles中对应的布局myTestView
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
-- Customize your theme here. -->
style>
<style name="NoDialogTitle" parent="@android:Theme.Dialog">
<item name="android:windowFrame">@null
- "android:windowNoTitle"
>true
- "android:windowBackground"
>@android:color/transparent
- "android:windowIsFloating">true
- "android:windowContentOverlay">@null
style>
<style name="myTextView">
<item name="android:background">@drawable/title_background
- "android:textAppearance"
>@android:style/TextAppearance.Large
- "android:textColor"
>@color/blue
style>
resources>
其中的名为NoDialogTitle的设置是老师给的去除边框圆角以外的部分的,引用的时候在代码中这样引用Dialog dialog=new Dialog(MainActivity.this,R.style.NoDialogTitle);
//drawable中的xml文件
//title
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android">
"@dimen/corners"
android:topRightRadius="@dimen/corners" />
"#0D7A29" />
/>
//对话框整体
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android">
"@dimen/corners" />
"#ffffff" />
"1dp"
android:color="#64251200" />
//右键
//按下去的时候
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android">
"@dimen/corners" />
"#ffffff" />
"1dp"
android:color="#64251200" />
//平常的时候
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android">
"@dimen/corners" />
"#ffffff" />
"1dp"
android:color="#64251200" />
//设置右键按键
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android">
- "@drawable/btn_right_pressed" android:state_pressed="true" />
- "@drawable/btn_right_normal"/>
//左键雷同设置,只是圆角设置为bottomLeftRadius
shape中颜色solid,边框stroke,圆角conrners
活动和昨天的一样,只是添加了一个Button来触发而已,具体的自定义方法见下面代码
//Activity
private void userDefinedDialog() {
// 应用自己设置的主题
dialog=new Dialog(MainActivity.this,R.style.NoDialogTitle);
// 获得并设置自定义Dialog
LayoutInflater inflater=getLayoutInflater();
View userDefinedDialog=inflater.inflate(R.layout.user_defined_dialog_layout, null);
TextView textView_title= (TextView) userDefinedDialog.findViewById(R.id.text_title);
TextView textView_message= (TextView) userDefinedDialog.findViewById(R.id.text_message);
Button button_y= (Button) userDefinedDialog.findViewById(R.id.button_y);
Button button_n= (Button) userDefinedDialog.findViewById(R.id.button_n);
Spanned spanned= Html.fromHtml("这是一个新的标题", new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
Drawable drawable=getResources().getDrawable(R.mipmap.ic_launcher);
drawable.setBounds(0,0,drawable.getIntrinsicHeight(),drawable.getIntrinsicWidth());
return drawable;
}
},null);
textView_title.setText(spanned);
textView_message.setText("这是一个新的内容");
button_y.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "点击确定", Toast.LENGTH_SHORT).show();
// 关闭dialog
dialog.dismiss();
}
});
button_n.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
// 去掉原有标题
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// 添加自己的View到dialog
dialog.setContentView(userDefinedDialog);
dialog.setCancelable(false);
dialog.show();
}
活动和上面的自定义Dialog一样,只是加了个button触发,具体代码实现如下。构造对象时DatePickerDialog(Context context, int theme, DatePickerDialog.OnDateSetListener listener, int year, int monthOfYear, int dayOfMonth)依次传入上下文,监听器,年,月,日。
下面的Demo中通过Calendar获得当前时间,将当前时间传入Dialog中。监听器中通过int year, int monthOfYear, int dayOfMonth监听Dialog的具体数据,并将数据传入Calendar中,通过getTime方法设置年月日,其中有用到SimpleDateFormat 造型。Calender.getTime()获得的是当前的时间,如果不加设置的话显示的就是当前时间。因为这里只设置了年月日,如果显示的时候加上小时分钟,小时分钟就是getTime得到的当前时间。这一点下面的TimePickerDialog中也一样,TimePickerDialog的例子中并没有设置年月日,但是显示的时候还是出现了当前的年月日。
private void dataPickerDialog() {
Calendar mCalendar=Calendar.getInstance();
DatePickerDialog datePickerDialog=new DatePickerDialog(MainActivity.this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mCalendar.set(year, monthOfYear, dayOfMonth);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy年MM月dd日");
// simpleDateFormat format(data):将data类型的值造型成"yyyy年MM月dd日",calecdar.getTime()返回data类型
Toast.makeText(getApplication(),"这个造型是"+simpleDateFormat.format(mCalendar.getTime()),Toast.LENGTH_SHORT).show();
}
},mCalendar.get(Calendar.YEAR),mCalendar.get(Calendar.MONTH),mCalendar.get(Calendar.DAY_OF_MONTH));
datePickerDialog.show();
}
对象的构造TimePickerDialog(Context context, TimePickerDialog.OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView),上下文,监听器,小时,分钟,最后一个参数,true对应24小时,false对应12小时
Calendar mCalendar=Calendar.getInstance();
TimePickerDialog dialog=new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
mCalendar.set(mCalendar.HOUR,hourOfDay);
mCalendar.set(mCalendar.MINUTE,minute);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy年MM月dd日HH:mm");
simpleDateFormat.format(mCalendar.getTime());
// 因为getTime返回的是现在这一时刻距离某年到现在的时间。所以除了规定传入的时间外,其余时间与手机同步
Toast.makeText(getApplicationContext(),"时间为"+simpleDateFormat.format(mCalendar.getTime()),Toast.LENGTH_SHORT).show();
}
},mCalendar.get(Calendar.HOUR),mCalendar.get(Calendar.MINUTE),true);
// },5,6,true);
dialog.show();
}
Dialog中有默认的布局,PopupWindow中没有默认的布局,必须自己设置。Demo中有一个onKeyDown方法,这个是手机按键的监听器,这里设置back的监听:PopupWindow运行的时候,点击back键关闭PopupWindow。注意加上PopupWindow为空是时候。具体使用方法见代码
//活动
public class MainActivity extends Activity implements View.OnClickListener{
private Button mBtn_pop;
private PopupWindow mPopupWindow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn_pop= (Button) findViewById(R.id.button_pop);
mBtn_pop.setOnClickListener(this);
}
// 监听手机按键
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK){
// 必须用短路与,如果mPopupWindow是null直接跳出,不再执行后面的判断条件
if(mPopupWindow!=null&&mPopupWindow.isShowing()){
mPopupWindow.dismiss();
// return true后这个方法内下面的语句就不执行了。
// 不返回true的话按back键会继续执行下面的语句,退出活动
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button_pop:
popupWindow();
break;
default:
break;
}
}
private void popupWindow() {
mPopupWindow=new PopupWindow(MainActivity.this);
// 设置宽高
mPopupWindow.setHeight(ActionBar.LayoutParams.WRAP_CONTENT);
mPopupWindow.setWidth(ActionBar.LayoutParams.MATCH_PARENT);
// 添加自定义view
View popupView=getLayoutInflater().inflate(R.layout.my_popupwindow,null);
mPopupWindow.setContentView(popupView);
// 点击Window以外的界面返回,必须在show之前设置
mPopupWindow.setOutsideTouchable(true);
// 在指定按键下面显示
mPopupWindow.showAsDropDown(mBtn_pop);
}
}
//main_activity
"http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
"@+id/button_pop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="PopupWindow测试"/>
//自定义的布局
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
"@+id/text_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_gravity="center_horizontal"
android:text="文本1"/>
"@+id/text_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_gravity="center_horizontal"
android:text="文本2"/>
"@+id/text_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_gravity="center_horizontal"
android:text="文本3"/>
手机上接收到的一些推送就是由这个实现的。NotificationManager 控制Notification的发送。PendingIntent 设置弹出界面的链接。
//活动
public class MainActivity extends Activity implements View.OnClickListener{
private Button mBtn1;
private Button mBtn2;
private Button mBtn3;
private NotificationManager mNotificationManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn1= (Button) findViewById(R.id.button_sendnew);
mBtn3= (Button) findViewById(R.id.button_sendold);
mBtn2= (Button) findViewById(R.id.button_cancel);
// 初始化notificationmanager
mNotificationManager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBtn1.setOnClickListener(this);
mBtn2.setOnClickListener(this);
mBtn3.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button_sendnew:
newNotification();
break;
case R.id.button_sendold:
oldNotification();
break;
case R.id.button_cancel:
mNotificationManager.cancel(1);//取消id为1的通知
break;
default:
break;
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void newNotification() {
Intent intent=new Intent(getApplicationContext(),MainActivity.class);//设置pendingintent事件
// 设置pendingintent使用方式
PendingIntent pend=PendingIntent.getActivity(getApplicationContext(), 1, intent, PendingIntent.FLAG_ONE_SHOT);
Notification notification=new Notification.Builder(MainActivity.this).setSmallIcon(R.mipmap.ic_launcher).setTicker("我是一条消息")
.setContentTitle("我是一个标题").setContentText("我是一个文本").setContentInfo("我是内容").setContentIntent(pend)
.setAutoCancel(true).setWhen(System.currentTimeMillis()).getNotification();//build
mNotificationManager.notify(1,notification);
}
private void oldNotification() {
Notification notification=new Notification();//初始化notification
notification.icon= R.mipmap.ic_launcher;//设置通知的图片
notification.tickerText="我是一个消息";//设置状态栏文本
notification.flags=Notification.FLAG_AUTO_CANCEL;//设置为可以取消
Intent intent=new Intent(getApplicationContext(),MainActivity.class);//设置pendingintent事件
// 设置pendingintent使用方式
PendingIntent pend=PendingIntent.getActivity(getApplicationContext(), 1, intent, PendingIntent.FLAG_ONE_SHOT);
// 设置pendingIntent显示的内容
notification.setLatestEventInfo(getApplicationContext(),"我是标题","我是内容",pend);
notification.when=System.currentTimeMillis();//设置触发时间or Calender.getInstance().getTimeInMillis()
mNotificationManager.notify(1,notification);//通知管理器将id为1的通知添加
}
}
//布局
"http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:orientation="vertical"
>
"@+id/button_sendold"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送消息(旧方法)" />
"@+id/button_sendnew"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送消息(新方法)" />
"@+id/button_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消消息" />