自学安卓权威编程指南(九)

一,这一章来说是用来创建对话框的,要使用对话框就要使用AlertDialog,我们应该将AlertDialog封装在DialogFragment(Fragment)的实例中使用,这样子通过使用FragmentManager来管理对话可以更加灵活地显示对话框。因为如果直接使用对话框的话,旋转设备时Dialog会消失,但是封装在fragment中的就不会有这样的问题存在,这样子要使用对话框,我们应该按下面的步骤来创建

(1)我们应该先创建一个fragment

(2)然后在fragment中去创建和配置显示对话框的实例

(3)然后由一个activity来托管上面创建的fragment。

也就是 对应创建(1)DatePickerFragment类(2)创建AlertDialog(3)借助FragmentManager在屏幕上显示对话框,最后应该配置使用DatePicker,和实现在CrimeFragment和DatePickerFragment之间去传递数据

二。创建DatePickerFragment新类,并设置DialogFragment超类为支持库中的DialogFragment类,然后去实现onCreateDialog(Bundle be)方法,然后为了在屏幕上去显示DialogFragment,托管的FragmentManager会去调用它,如下面的代码:

public class DateDialogFragment extends DialogFragment {

public Dialog onCreateDialog(Bundle savedInstanceState){

return new AlertDialog.Builder(getActivity())

                  .setTitle();

                  .setPositiveButton();.create();

}

}

三.要显示DialogFragment,和其他的fragment一样,DialogFragment实例也是由托管activity的FragmentManager来管理的,要将DialogFragment添加给FragmentManager管理并放置在屏幕上,可以调用fragment的以下方法,

public void show(FragmentManager manager,String tag);

public void show(FragmentTransation transation,String tag)

String参数是可以唯一识别FragmentManager队列中的DialogFragment,两个方法都可以使用,但后面那个需要我们自己负责创建和提交事务,前者的话会自动创建和提交事务,

四。我们在需要显示的碎片里面来添加一个tag,然后再onCreateView()方法中,去展示DatePickerFragment的界面

public class CrimeFragment extends Fragment {

private static final String DIALOG_DATE = "DialogDate";

public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){

mButton.setOnClickListener(new View.OnClickListener(){

public void onClick(View v){

FragmentManager manager = getFragmentManager();

DatePickerFragment dialog = new DatePickerFragment();

dialog.show(manager,DIALOG_DATE);

}

});

}

}

五.设置对话框中要显示的内容,应该使用AlertDialog的setView()方法,该方法配置对话框,实现在标题栏和按钮之间去显示传入的View对象,在项目工具窗口中,以DatePicker为根目录,创建名为dial_date.xml的布局文件,新布局里面只有一个View的对象,就是我们生成和传递给setView()方法的DatePicker视图,

然后在onCreateDialog()方法中去实例化DatePicker视图和添加给对话框,如下面的代码:

View v = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_date,null);

然后在AlertDialog.Builder()后面添加setView(v);

其实,我们也可以使用代码来添加对象,但是我们还是使用定义xml布局文件的方法好,因为使用布局文件的时候,想要调整布局文件会容易一些,还有就是但设备旋转时,用户选择的日期也会得到保留,这是因为设备配置改变时,具有ID属性的视图可以保存运行状态,我们使用布局的时候,编译的工具已经为DatePicker生成了唯一的ID。

六.fragment间的数据传递。要实现同一activity中两个fragment之间的数据传递,那么可以新建立一个newInstance(Date),然后将Date作为argument附加给fragment,为返回新日期给接受的fragment,并更新模型层,和对应的视图,那么就需要将日期打包好为extra并附加到Intent上面,然后调用Crime.onActivityResult()方法,并传入准备好的Intent,

下面时传送数据给DatePickerFragment,创建和设置fragment argument通常是在newInstance()方法中完成的,

public class DatePickerFragment extends DialogFragment {

private static final String ARG_DATE = "date";

private DatePicker mDatePicker;

public static DatePickerFragment newInstance(Date date) {

Bundle args = new Bundle();

args.putSerializable(ARG_DATE,date);

DatePickerFragment fragment = new DatePickerFragment();

fragment.setArgument(args);

return fragment;

}

}

 

然后在CrimeFragment中,用DatePickerFragment.newInstance(Date)方法来替换DatePickerFragment的构造方法。

换成DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());

 

七.对应DatePickerFragment,DatePicker对象的初始化需要整数形式的月,日,年,但date无法直接提供整数,那么对应着。我们就需要使用一个Calendar对象,然后用Date来配置它,再从Calendar对象中去获得所需要的东西

下面是在onCreateDialog()方法中,从argument中获取Date对象,然后用它和Calendar对象初始化DatePicker;

Date date = (Date)getArguments().getSerializable(ARG_DATE);

Calendar calendar = Calendar.getInstance();

calendar.setTime(Date);

int year = calendar.get(Calendar.YEAR);

int month = calendar.get(Calendar.MONTH);

int day = calendar.get(Calendar.DAY_OF_MONTH);

 

mDatePicker = (DatePicker)v.findViewById(R.id.dialog_date_picker);

mDatePicker.init(year,month,day,null);

 

按照上面的做法我们就完成了从CrimeFragment向DatePickerFragment传递日期

八.这边是传递数据给CrimeFragment

如果是activity的数据回传,那么我们调用startAvtivityForResult()方法,ActivityManager负责跟踪管理activity父子关系,回传数据后,子activity被销毁,但ActivityManager知道接受数据的是哪一个activity

但对于fragment来说,我们需要通过设置他们的目标fragment来建立关系,运用setTargetFragment(Fragment fragment,int requestCode),第一个参数是目标fragment,第二个是请求代码,

目标fragment和请求代码由FragmentManager负责管理,我们可以调用fragment(设置目标fragment的fragment)的getTargetFragment()方法和getTargetRequestCode()来获取他们使用下面的代码

在CrimeFragment中使用下面的代码:

private static final int REQUEST = 0;

在呈现dialog前添加下面的代码:

dialog.setTargetFragment(CrimeFragment.this,REQUEST_DATE);

当建立好CrimeFragment与DatePickerFragment之间的关系后,就需要将数据回传给CrimeFragment了,回传日期将作为extra附加给Intent.

我们会让DatePickerFragment类调用CrimeFragment.onActivityResult(int,int,Intent)方法,这样我们应该在DatePickerFragment类中去新建一个sendResult()私有方法,创建intent并将日期数据作为extra附加到intent上,最后调用Crime.onActivityResult()方法,如下面的代码:

在DatePickerFragment中

public static final String EXTRA_DATE = "com.bignerdra.....";

private void sendResult(int resultCode,Date date){

if(getTargetFragment()==null){

return;

}

Intent  intent = new Intent();

intent.putExtra(EXTRA_DATE,date);

getTargetFragment().onActivityResult(getTargetRequestCode(),resultCode,intent);

}

 

然后我们就可以在onClick()方法中去获得日期并调用sendResult()方法,

 

最后我们应该在CrimeFragment中去覆盖onActivityResult(),从extra中去获得日期数据,设置对应的Crime的记录日期,然后刷新日期按钮的显示,如下面的代码:

public void onActivityResult(int requestCode,int resultCode,Intent date){

if(resultCode !=Activity.RESULT_OK){

return;

}

if(requestCode == REQUEST_DATE){

Date date = (Date)date.getSerializableExtra(DatePickerFragment.EXTRA_DATE);

mCrime.setDate(Date);

mDateButton.setText(mCrime.getDate().toString());

}

}

而对于重复的代码。我们可以把他们放在一个私有的方法中去,右击 Refactor -> Extrat ->Method

九.对于需要更加灵活的DialogFeagment视图展示的话,如果是平板屏幕比较大的,那么就适合以对话框的方式来显示信息和接受用户输入,这种情况就应该设置目标的fragment并调用fragment的show方法,当对话框被取消之后,对话框fragment会调用目标fragment的onActivityResult()方法,无论启动子activity还是显示对话框,fragment的onActivityResult()方法总会被调用的,因此可以使用相同的代码来实现不同的信息呈现

如果要编写相同的代码用于全屏的fragment或是对话框fragment,可以选择覆盖DialogFragment.onCreateView(),而不是onCreateDialog()方法

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值