一、PopupWindow,在学了自定义对话框后紧接着学习“弹出窗”
1.弹出窗和对话框(PopupWindow和AlertDialog)的异同点,一搜一大堆,一般而言:PopupWindow不像AlertDialog那么霸道,它不会抢夺焦点,以下运行结果可以看出。
2.PopupWindow的实现步骤。
第一步:自定义.xml布局文件;
第二步:获取LayoutInflate对象;
第三步:调用inflate()方法获取View对象;
第四步:创建PopupWindow对象;
第五步:调用PopupWindow的showAsDropDown或者showAsLocation方法显示对话窗口。
3.重复利用上节代码,只是在activity_main.xml中多添加一个按钮,沿用自定义的define_dialog.xml这里直接贴出MainActivity.java文件代码:
package com.oldtogether.defineddialog;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnTest = (Button) findViewById(R.id.btn_test);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "PopupWindow不像AlertDialog那样霸道,他不会抢夺焦点的", Toast.LENGTH_LONG).show();
}
});
}
PopupWindow popupWindow;
public void btnClick(View v){
LayoutInflater inflater = LayoutInflater.from(this);
View myView = inflater.inflate(R.layout.define_dialog, null);
popupWindow = new PopupWindow(myView, 400, 500);//后两个参数单位是像素px,对话框的长和高
myView.findViewById(R.id.btn_sure).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
Toast.makeText(MainActivity.this, "点击了确定", Toast.LENGTH_LONG).show();
}
});
//显示方式,只设置含一个参数的下拉方法,参数是锚定点,指明在那个锚定控件下会出现该弹出窗
popupWindow.showAsDropDown(v);
}
}
3.运行结果
二、使用Activity实现类似对话框
1.知识是相通的,可以设置Activity的相关属性,来实现类似对话框。
2.MainActivity2.java中显示主布局,代码如下:
package com.oldtogether.defineddialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity2 extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnTest = (Button) findViewById(R.id.btn_test);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity2.this, "PopupWindow不像AlertDialog那样霸道,他不会抢夺焦点的", Toast.LENGTH_LONG).show();
}
});
}
public void btnClick(View v) {
Intent intent = new Intent(this, DialogActivity.class);
startActivity(intent);
}
}
3.在DialogActivity.java中设置显示自定义的布局,很简单,代码如下:
package com.oldtogether.defineddialog;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
public class DialogActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.define_dialog);
findViewById(R.id.btn_sure).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
4.运行结果:
5.从上面的运行结果可以看出,在对话框形式上只会达到了类同,而区别甚大,细心的人会发现,DialogActivity上面有软件图标,和我们定义的project,然而只需要两行代码可以改变这一现象。
1):
//第一步:在AndroidManifest.xml文件中设置style下的theme为Dialog
<activity
android:name=".DialogActivity"
android:theme="@android:style/Theme.Dialog">
</activity>
2):
//第二步:设置Activity的窗口风格,注意在加载布局之前加代码,代码如下:
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.define_dialog);
3):运行结果:
三、AlertDialog家族中还有其他对话框,如ProgressDialog(进度对话框)、DatePickerDialog(日期选择对话框)、TimePickerDialog(时间选择对话框)
1.日期选择对话框,代码如下:
package com.oldtogether.defineddialog;
import java.util.Calendar;
import android.app.DatePickerDialog;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.Toast;
public class MainActivity3 extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnTest = (Button) findViewById(R.id.btn_test);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity3.this, "PopupWindow不像AlertDialog那样霸道,他不会抢夺焦点的", Toast.LENGTH_LONG).show();
}
});
}
public void btnClick(View v) {
//获得系统的时间对象
Calendar c = Calendar.getInstance();
//创建一个DatePickerDialog对话框,并将它显示
new DatePickerDialog(this,
//绑定监听器(我们可以修改和选择时间当然少不了监听器)
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
String text = "您选择了:"+year+"年"+(monthOfYear+1)+"月"+dayOfMonth+"日";
Toast.makeText(MainActivity3.this, text, Toast.LENGTH_LONG).show();
}
},
c.get(Calendar.YEAR),
c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH)).show();
}
}
2.运行结果:
3.TimePickerDialog(时间选择对话框),直接贴关键代码
public void btnClick(View v) {
//获得系统的时间对象
Calendar c = Calendar.getInstance();
//创建一个TimePickerDialog对话框,并将它显示
new TimePickerDialog(this,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
String text = "您选择了:"+hourOfDay+"时"+minute+"分";
Toast.makeText(MainActivity4.this, text, Toast.LENGTH_LONG).show();
}
},
//设置初始时间
c.get(Calendar.HOUR_OF_DAY),
c.get(Calendar.MINUTE),
//是否为24小时制
true).show();
}
4.运行结果
四、进度对话框(日常生活中很常见进度对话框,比如说加载游戏时的进度条,安装某款软件时的进度条)。
1.简单环形进度对话框,代码如下
package com.oldtogether.defineddialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity5 extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnTest = (Button) findViewById(R.id.btn_test);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity5.this, "PopupWindow不像AlertDialog那样霸道,他不会抢夺焦点的", Toast.LENGTH_LONG).show();
}
});
}
ProgressDialog pd;
public void showProgress(){
pd = new ProgressDialog(this);
pd.setTitle("正在玩命加载中......");
pd.setMessage("请您稍等");
pd.setCancelable(true);//设置可取消,比如我们在加载游戏界面时间过长时,会怀疑网连上了没有,此时需要取消
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);//设置进度条显示的风格,当然默认为圆圈
pd.show();
}
public void btnClick(View v) {
showProgress();
}
}
1.1运行结果
2.虽然上面的环形进度条显示了,但是没有什么意义,因为我们不知道它到底进行什么耗时操作,那怎么设置耗时操作呢?直接贴代码:
package com.oldtogether.defineddialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity5 extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnTest = (Button) findViewById(R.id.btn_test);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity5.this, "PopupWindow不像AlertDialog那样霸道,他不会抢夺焦点的", Toast.LENGTH_LONG).show();
}
});
}
ProgressDialog pd;
public void showProgress(){
pd = new ProgressDialog(this);
pd.setTitle("正在玩命加载中......");
pd.setMessage("请您稍等");
pd.setCancelable(true);//设置可取消,比如我们在加载游戏界面时间过长时,会怀疑网连上了没有,此时需要取消
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);//设置进度条显示的风格,当然默认为圆圈
pd.show();
}
//Handler线程之间的通讯,作用等同于Activity之间的Intent
Handler handler = new Handler(){
@Override
//主线程(UI线程)
public void handleMessage(Message msg) {//接受子线程的消息
pd.dismiss();
}
};
public void btnClick(View v) {
/*
* 点击按钮发生两件事情,并且是并行的(因为new Thread)
* 1、环形进度条旋转;
* 2、子线程运行。
*/
showProgress();
//创建一个子线程(new Thread然后点出start,最后重写run)
new Thread(){
public void run() {
for(int i=0;i<3;i++){
try {
Thread.sleep(1000);//循环一次睡1秒(总共睡三秒),注意单位是毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
handler.sendEmptyMessage(0);//发送消息,在子线程里面
};
}.start();
}
}
2.1运行结果
3.水平进度条的进度实现,代码如下:
package com.oldtogether.defineddialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity6 extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnTest = (Button) findViewById(R.id.btn_test);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity6.this, "PopupWindow不像AlertDialog那样霸道,他不会抢夺焦点的", Toast.LENGTH_LONG).show();
}
});
}
ProgressDialog pd;
public void showProgress(){
pd = new ProgressDialog(this);
pd.setTitle("正在玩命加载中......");
pd.setMessage("请您稍等");
pd.setCancelable(true);//设置可取消,比如我们在加载游戏界面时间过长时,会怀疑网连上了没有,此时需要取消
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//设置进度条显示的风格
pd.setMax(10);//设置总量
pd.show();
}
//Handler线程之间的通讯,作用等同于Activity之间的Intent
Handler handler = new Handler(){
@Override
//主线程(UI线程)
public void handleMessage(Message msg) {//接受子线程的消息
if(msg.what == 0){
pd.dismiss();
}else if(msg.what == 1){
pd.setProgress(msg.arg1);
}
}
};
public void btnClick(View v) {
/*
* 点击按钮发生两件事情,并且是并行的(因为new Thread)
* 1、条形进度条递增;
* 2、子线程运行。
*/
showProgress();
//创建一个子线程(new Thread然后点出start,最后重写run)
new Thread(){
public void run() {
for(int i=1;i<=10;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = Message.obtain();//为了节省资源
msg.arg1=i;
msg.what=1;
handler.sendMessage(msg);
}
handler.sendEmptyMessage(0);//发送消息,在子线程里面
};
}.start();
}
}
3.1运行结果