亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Android應(yīng)用中DialogFragment的基本用法

 更新時(shí)間:2016年05月11日 11:24:08   作者:風(fēng)荷舉  
Android App中建議使用DialogFragment作為對(duì)話(huà)框的容器,DialogFragment類(lèi)提供了創(chuàng)建對(duì)話(huà)框并管理其外觀(guān)需要的所有控件,本文主要內(nèi)容便為詳解Android應(yīng)用中DialogFragment的基本用法,而不再需要調(diào)用Dialog的方法需要的朋友可以參考下

DialogFragment的基本用法
1. 創(chuàng)建DialogFragment

public class DialogA extends DialogFragment implements DialogInterface.OnClickListener {

 @Override
 public Dialog onCreateDialog(Bundle savedInstanceState) {
  AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
  builder.setMessage(R.string.dialoga_title)
    .setPositiveButton(R.string.ok, this)
    .setNegativeButton(R.string.cancel, this);

  return builder.create();
 } 

 @Override
 public void onClick(DialogInterface dialog, int id) {
  switch(id) {
   case AlertDialog.BUTTON_NEGATIVE:
    Toast.makeText(getActivity(), "Negative", Toast.LENGTH_SHORT).show();
    break;
   case AlertDialog.BUTTON_POSITIVE:
    Toast.makeText(getActivity(), "Positive", Toast.LENGTH_SHORT).show();
    break;
   default:
    break;
  } 
 } 
}

說(shuō)明:自定義一個(gè)DialogFragment,并重寫(xiě)它的onCreateDialog()方法。
2. 調(diào)用該DialogFragment
下面是在FragmentActivity中調(diào)用該DialogFragment對(duì)話(huà)框。

public class DialogTest extends FragmentActivity {

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  showDialog();
 }

 private void showDialog() {
  FragmentManager fm = getSupportFragmentManager();
  DialogA dialoga = new DialogA();
  dialoga.show(fm, "fragmenta");
 }
}

自定義DialogFragment布局
下面介紹自定義DialogFragment的布局的方法
點(diǎn)擊查看:自定義DialogFragment布局的完整代碼
1. 設(shè)置布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="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:orientation="vertical" >

 <TextView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/dialoga_intro" />

 <ImageView
  android:id="@+id/image"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:src="@drawable/ic_action_video" />

</LinearLayout>

2. 使用布局

public class DialogA extends DialogFragment implements DialogInterface.OnClickListener {

 @Override
 public Dialog onCreateDialog(Bundle savedInstanceState) {
  AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
  LayoutInflater inflater = getActivity().getLayoutInflater();
  builder.setView(inflater.inflate(R.layout.dialoga, null))
    .setMessage(R.string.dialoga_title)
    .setPositiveButton(R.string.ok, this)
    .setNegativeButton(R.string.cancel, this);

  return builder.create();
 }

 @Override
 public void onClick(DialogInterface dialog, int id) {
  switch(id) {
   case AlertDialog.BUTTON_NEGATIVE:
    Toast.makeText(getActivity(), "Negative", Toast.LENGTH_SHORT).show();
    break;
   case AlertDialog.BUTTON_POSITIVE:
    Toast.makeText(getActivity(), "Positive", Toast.LENGTH_SHORT).show();
    break;
   default:
    break;
  }
 }
}

DialogFragment和Activity的交互
下面介紹自定義DialogFragment和Activity交互的方法
點(diǎn)擊查看:DialogFragment和Activity交互的完整代碼
1. 定義通信接口
在DialogFragment中定義它們之間的通信接口。

public interface NoticeDialogListener {
 public void onDialogPositiveClick(DialogFragment dialog);
 public void onDialogNegativeClick(DialogFragment dialog);
} 

// Use this instance of the interface to deliver action events
NoticeDialogListener mListener;

// Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
@Override
public void onAttach(Activity activity) {
 super.onAttach(activity);
 // Verify that the host activity implements the callback interface
 try {
  // Instantiate the NoticeDialogListener so we can send events to the host
  mListener = (NoticeDialogListener) activity;
 } catch (ClassCastException e) {
  // The activity doesn't implement the interface, throw exception
  throw new ClassCastException(activity.toString()
    + " must implement NoticeDialogListener");
 } 
} 

2. 在DialogFragment中調(diào)用該接口

@Override
public void onClick(DialogInterface dialog, int id) {
 switch(id) {
  case AlertDialog.BUTTON_POSITIVE:
   //Toast.makeText(getActivity(), "Negative", Toast.LENGTH_SHORT).show();
   mListener.onDialogPositiveClick(DialogA.this);
   break;
  case AlertDialog.BUTTON_NEGATIVE:
   //Toast.makeText(getActivity(), "Positive", Toast.LENGTH_SHORT).show();
   mListener.onDialogNegativeClick(DialogA.this);
   break;
  default:
   break;
 } 
}

3. 在A(yíng)ctivity中實(shí)現(xiàn)該接口

public class DialogTest extends FragmentActivity 
 implements DialogA.NoticeDialogListener {

 ...

 @Override
 public void onDialogPositiveClick(DialogFragment dialog) {
  Toast.makeText(this, "Positive Callback", Toast.LENGTH_SHORT).show();
 }
 @Override
 public void onDialogNegativeClick(DialogFragment dialog) {
  Toast.makeText(this, "Negative Callback", Toast.LENGTH_SHORT).show();
 }
}

Dialog與DialogFragment的對(duì)比
從代碼的編寫(xiě)角度看,Dialog使用起來(lái)要更為簡(jiǎn)單,但是Google則是推薦盡量使用DialogFragment(對(duì)于A(yíng)ndroid 3.0以下的版本,可以結(jié)合使用support包中提供的DialogFragment以及FragmentActivity)。今天試著用這兩種方式來(lái)創(chuàng)建對(duì)話(huà)框,發(fā)現(xiàn)DialogFragment果然有一個(gè)非常好的特性(在手機(jī)配置變化,導(dǎo)致Activity需要重新創(chuàng)建時(shí),例如旋屏,基于DialogFragment的對(duì)話(huà)框?qū)?huì)由FragmentManager自動(dòng)重建,然而基于Dialog實(shí)現(xiàn)的對(duì)話(huà)框則沒(méi)有這樣的能力)。

下面是兩段實(shí)例代碼:

他們使用的界面都一樣:(dialog.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >
 
 <ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:src="@drawable/ic_launcher" />
 
</LinearLayout>

1.基于Dialog實(shí)現(xiàn)的對(duì)話(huà)框

public class MainActivity extends Activity {
 private Button clk;
 private Dialog dialog;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
   
  clk = (Button) findViewById(R.id.clk);
  dialog = new Dialog(this);
  dialog.setContentView(R.layout.dialog);
  clk.setOnClickListener(new OnClickListener() {
    
   @Override
   public void onClick(View v) {
    dialog.show();
   }
  });
 }
}

當(dāng)我們點(diǎn)擊按鈕時(shí),會(huì)彈出對(duì)話(huà)框(內(nèi)容為android logo),當(dāng)我們旋轉(zhuǎn)屏幕后,Activity重新創(chuàng)建,整個(gè)Activity的界面沒(méi)有問(wèn)題,而對(duì)話(huà)框消失了。
除此之外,其實(shí)還有一個(gè)問(wèn)題,就是在logcat中會(huì)看到異常信息:Android..leaked .. window,這是因?yàn)樵贏(yíng)ctivity結(jié)束之前,Android要求所有的Dialog必須要關(guān)閉。我們旋屏后,Activity會(huì)被重建,而上面的代碼邏輯并沒(méi)有考慮到對(duì)話(huà)框的狀態(tài)以及是否已關(guān)閉。

于是將上述代碼修改為:

public class MainActivity extends Activity {
 private Button clk;
 private Dialog dialog;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
   
  clk = (Button) findViewById(R.id.clk);
  dialog = new Dialog(this);
  dialog.setContentView(R.layout.dialog);
  clk.setOnClickListener(new OnClickListener() {
    
   @Override
   public void onClick(View v) {
    dialog.show();
   }
  });
 
  //用戶(hù)恢復(fù)對(duì)話(huà)框的狀態(tài)
  if(savedInstanceState != null && savedInstanceState.getBoolean("dialog_show"))
   clk.performClick();
 }
 
 /**
  * 用于保存對(duì)話(huà)框的狀態(tài)以便恢復(fù)
  */
 @Override
 protected void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  if(dialog != null && dialog.isShowing())
   outState.putBoolean("dialog_show", true);
  else
   outState.putBoolean("dialog_show", false);
 }
 
 /**
  * 在A(yíng)ctivity銷(xiāo)毀之前,確保對(duì)話(huà)框以關(guān)閉
  */
 @Override
 protected void onDestroy() {
  super.onDestroy();
  if(dialog != null && dialog.isShowing())
   dialog.dismiss();
 }
}


2. 基于DialogFragment的對(duì)話(huà)框

與上面的對(duì)話(huà)框使用同樣的界面布局,此處僅僅展現(xiàn)一個(gè)簡(jiǎn)單對(duì)話(huà)框,因此只重寫(xiě)了onCreateView方法

public class MyDialogFragment extends DialogFragment {
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
  View v = inflater.inflate(R.layout.dialog, container, false);
  return v;
 }
}

public class MainActivity extends FragmentActivity {
 private Button clk;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
   
  clk = (Button) findViewById(R.id.clk);
  clk.setOnClickListener(new OnClickListener() {
    
   @Override
   public void onClick(View v) {
    MyDialogFragment mdf = new MyDialogFragment();
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    mdf.show(ft, "df");
   }
  });
 }
}


這兩段代碼可以實(shí)現(xiàn)第一種方式的同樣功能,此處我們并沒(méi)有去關(guān)心對(duì)話(huà)框的重建,以及Activity銷(xiāo)毀前對(duì)話(huà)框是否已關(guān)閉,這一切都是由FragmentManager來(lái)管理。
其實(shí)DialogFragment還擁有fragment的優(yōu)點(diǎn),即可以在一個(gè)Activity內(nèi)部實(shí)現(xiàn)回退(因?yàn)镕ragmentManager會(huì)管理一個(gè)回退棧)

相關(guān)文章

最新評(píng)論