(个人经验,仅供参考,错误之处,敬请谅解)
缘由
个人在写Android开发实验的时候,因为要使用AlertDialog的builder进行自定义Dialog并显示,
代码如下:
MainActivity:
package cn.cslg.exp_3_2_z09416221;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.*;
import java.text.DecimalFormat;
public class MainActivity extends Activity {
private EditText heiTxt,weiTxt;
private RadioButton radioMan,radioWoman;
private Button showReport;
private View dialogView;
private ImageView img;
private TextView bmiTxt,stateTxt,standardTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
showReport.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(radioMan.isChecked()||radioWoman.isChecked()){
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("您的BMI指数");
setDialogView();
builder.setView(dialogView);
builder.setNegativeButton("我知道了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
}else {
Toast.makeText(MainActivity.this,"请选择您的性别",Toast.LENGTH_SHORT).show();
}
}
});
}
public void init(){
heiTxt = (EditText)findViewById(R.id.height);
weiTxt = (EditText)findViewById(R.id.weight);
radioMan = (RadioButton)findViewById(R.id.radioMan);
radioWoman = (RadioButton)findViewById(R.id.radioWoman);
showReport = (Button)findViewById(R.id.showBtn);
dialogView = LayoutInflater.from(MainActivity.this).inflate(R.layout.report,null);
img = (ImageView)dialogView.findViewById(R.id.img);
bmiTxt = (TextView)dialogView.findViewById(R.id.bmi);
stateTxt = (TextView)dialogView.findViewById(R.id.state);
standardTxt = (TextView)dialogView.findViewById(R.id.standard);
}
public void setDialogView(){
int state=0;
float height = Float.parseFloat(heiTxt.getText().toString());
float weight = Float.parseFloat(weiTxt.getText().toString());
float bmi_num = weight/(height*height);
float bmi = (float)(Math.round(bmi_num*100)/100);
if(bmi<18.5){
state = 1;
}else if(bmi<24){
state = 2;
}else if(bmi<28){
state = 3;
}else if(bmi<30){
state = 4;
}else if(bmi<40){
state = 5;
}else {
state = 6;
}
float standardNum = 0;
if(radioMan.isChecked()){
standardNum = height*height*22;
}else {
standardNum = height*height*20;
}
DecimalFormat decimalFormat = new DecimalFormat(".0");
String standard = decimalFormat.format(standardNum);
bmiTxt.setText("体质指数:"+bmi);
standardTxt.setText("标准体重:"+standard);
switch (state){
case 1: img.setImageResource(R.drawable.img1);stateTxt.setText("身体状态:偏瘦");break;
case 2: img.setImageResource(R.drawable.img2);stateTxt.setText("身体状态:正常");break;
case 3: img.setImageResource(R.drawable.img3);stateTxt.setText("身体状态:偏胖");break;
case 4: img.setImageResource(R.drawable.img4);stateTxt.setText("身体状态:肥胖");break;
case 5: img.setImageResource(R.drawable.img5);stateTxt.setText("身体状态:重度肥胖");break;
case 6: img.setImageResource(R.drawable.img6);stateTxt.setText("身体状态:极重度肥胖");break;
}
}
}
在第二次调用builder.show()的时候,程序便会崩溃,提示需要使用removeView().
解决方案
1、每次使用builder.setView()的时候一定要使用 LayoutInflater.from(context).inflate()方法,也就是说所显示的View是新转化的,与上一个View不一样,所以每次显示的是不一样的View,则不会崩溃。
2、个人猜测实际第一种解决方案会消耗内存,因为每次新转化的View并没有进行销毁。所以并不稳妥,最好的方案就是调用dialog.dismiss()方法,但dialog对象需要进行传入,看到有些方案是使用builder.create()返回dialog对象,这里可惜并不适用(dialog.show()也会返回dialog对象,很少使用到)。
3、实际代码错误运行提示中给出需要removeView(),一开始并不知道怎么调用,最后请教老师给出了调用方法:
if(dialogView.getParent()!=null){
ViewGroup vg = (ViewGroup)dialogView.getParent();
vg.removeView(dialogView);
}
这种方法其实最佳,在builder.setView()之前使用就删除了上一个dialogView。
第一种方法改后代码:
package cn.cslg.exp_3_2_z09416221;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.*;
import java.text.DecimalFormat;
public class MainActivity extends Activity {
private EditText heiTxt,weiTxt;
private RadioButton radioMan,radioWoman;
private Button showReport;
private View dialogView;
private ImageView img;
private TextView bmiTxt,stateTxt,standardTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
showReport.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(radioMan.isChecked()||radioWoman.isChecked()){
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("您的BMI指数");
dialogView = LayoutInflater.from(MainActivity.this).inflate(R.layout.report,null);
setDialogView();
builder.setView(dialogView);
builder.setNegativeButton("我知道了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
}else {
Toast.makeText(MainActivity.this,"请选择您的性别",Toast.LENGTH_SHORT).show();
}
}
});
}
public void init(){
heiTxt = (EditText)findViewById(R.id.height);
weiTxt = (EditText)findViewById(R.id.weight);
radioMan = (RadioButton)findViewById(R.id.radioMan);
radioWoman = (RadioButton)findViewById(R.id.radioWoman);
showReport = (Button)findViewById(R.id.showBtn);
}
public void setDialogView(){
img = (ImageView)dialogView.findViewById(R.id.img);
bmiTxt = (TextView)dialogView.findViewById(R.id.bmi);
stateTxt = (TextView)dialogView.findViewById(R.id.state);
standardTxt = (TextView)dialogView.findViewById(R.id.standard);
int state=0;
float height = Float.parseFloat(heiTxt.getText().toString());
float weight = Float.parseFloat(weiTxt.getText().toString());
float bmi_num = weight/(height*height);
float bmi = (float)(Math.round(bmi_num*100)/100);
if(bmi<18.5){
state = 1;
}else if(bmi<24){
state = 2;
}else if(bmi<28){
state = 3;
}else if(bmi<30){
state = 4;
}else if(bmi<40){
state = 5;
}else {
state = 6;
}
float standardNum = 0;
if(radioMan.isChecked()){
standardNum = height*height*22;
}else {
standardNum = height*height*20;
}
DecimalFormat decimalFormat = new DecimalFormat(".0");
String standard = decimalFormat.format(standardNum);
bmiTxt.setText("体质指数:"+bmi);
standardTxt.setText("标准体重:"+standard);
switch (state){
case 1: img.setImageResource(R.drawable.img1);stateTxt.setText("身体状态:偏瘦");break;
case 2: img.setImageResource(R.drawable.img2);stateTxt.setText("身体状态:正常");break;
case 3: img.setImageResource(R.drawable.img3);stateTxt.setText("身体状态:偏胖");break;
case 4: img.setImageResource(R.drawable.img4);stateTxt.setText("身体状态:肥胖");break;
case 5: img.setImageResource(R.drawable.img5);stateTxt.setText("身体状态:重度肥胖");break;
case 6: img.setImageResource(R.drawable.img6);stateTxt.setText("身体状态:极重度肥胖");break;
}
}
}