PreferenceFragment & DialogFragment & Spinner & NumberPicker

PreferencFragment解析:http://blog.csdn.net/lmj623565791/article/details/37970961/

billing_cycle.xml

<?xml version="1.0" encoding="UTF-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="@string/data_usage_summary_title">
    
    <Preference
        android:key="billing_cycle"
        android:title="@string/billing_cycle"/>
    
    <Preference 
        android:key="data_warning"
        android:title="@string/data_warning"/>
    
    <SwitchPreference
        android:key="set_data_limit"
        android:title="@string/set_data_limit"/>
    
    <Preference
        android:key="data_limit"
        android:title="@string/data_limit"/>
</PreferenceScreen>
data_usage_bytes_editor.xml
<?xml version="1.0" encoding="UTF-8"?>

<LinearLayout xmlns:android:"http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:gravity="center"
    android:paddingStart="16dp"
    android:paddingEnd="16dp"
    android:layout_width="match_parent"
    android:layot_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android">
    
    <EditText 
        android:id="@+id/bytes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:minWidth="48dip"
        android:layout_gravity="center_vertical"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:inputType="numberDecimal"/>
    
    <Spinner 
        android:id="@+id/size_spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:entries="@array/bytes_picker_sizes"/>
</LinearLayout>
data_usage_cycle_editor.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal" 
    android:gravity="center">
    
    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/data_usage_cycle_editor_subtitle"/>
    
    <NumberPicker 
        android:id="@+id/cycle_day"
        android:layout_width="48dip"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginStart="16dip"
        android:layout_marginEnd="16dip"
        android:focusable="true"
        android:focusableInTouchMode="true"/>
    

</LinearLayout>
BillingCycleSettings.java(这里的DataUsageBase是PreferenceFragment的子类)
package com.example.util;

import android.app.AlertDialog;
import android.net.NetworkTemplate;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.Preference;
import android.support.v14.preference.SwitchPreference;
import android.text.format.Time;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.NumberPicker;
import android.widget.Spinner;

public class BillingCycleSettings extends DataUsageBase implements
		Preference.OnPreferenceChangeListener{
	
	private static final String TAG="BillingCycleSettings";
	private static final boolean LOGO=true;
	
	private static final String TAG_CONFIRM_LIMIT="confirmLimit";
	private static final String TAG_CYCLE_EDITOR="cycleEditor";
	private static final String TAG_WARNING_EDITOR="warningEditor";
	
	private static final String KEY_BILLING_CYCLE="billing_cycle";
	private static final String KEY_DATA_WARNING="data_warning";
	private static final String KEY_SET_DATA_LIMIT="set_data_limit";
	private static final String KEY_DATA_LIMIT="data_limit";
	
	private NetworkTemplate mNetworkTemplate;
	private Preference mBillingCycle;
	private Preference mDataWarning;
	private android.preference.SwitchPreference mEnableDataLimit;
	private android.preference.Preference mDataLimit;
	private DataUsageController mDataUsageController;
	
	@Override
	public void onCreate(Bundle icicle){
		super.onCreate(icicle);
		mDataUsageController=new DataUsageController(getContext());
		
		Bundle args=getArguments();
		mNetworkTemplate=args.getParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE);
		
		addPreferencesFromResource(R.xml.billing_cycle);
		mBillingCycle=findPreference(KEY_BILLING_CYCLE);
		mDataWarning=findPreference(KEY_DATA_WARNING);
		mEnableDataLimit=(SwitchPreference)findPreference(KEY_SET_DATA_LIMIT);
		mEnableDataLimit.setOnPreferenceChangeListener(this);
		mDataLimit=findPreference(KEY_DATA_LIMIT);
	}
	
	@Override
	public void onResume(){
		super.onResume();
		updatePrefs();
	}
	
	private void updatePrefs(){
		NetworkPolicy policy=services.mPolicyEditor.getPolicy(mNetworkTemplate);
		mBillingCycle.setSummary(getString(R.string.billing_cycle_summary,policy!=null?
				policy.cycleDay:1));
		mDataWarning.setSummary(Formatter.formatFileSize(getContext(),policy!=null?
				policy.warningBytes:DataUsageController.DEFAULT_WARNING_LEVEL));
		if(policy!=null && policy.limitBytes!=LIMIT_DISABLED){
			mDataLimit.setSummary(Formatter.formatFileSize(getContext(),policy.limitBytes));
			mDataLimit.setEnabled(true);
			mEnableDataLimit.setChecked(true);
		}else{
			mDataLimit.setSummary(null);
			mDataLimit.setEnabled(false);
			mEnableDataLimit.setChecked(false);
		}
	}
	
	@Override
	public boolean onPreferenceTreeClick(Preference preference){
		if(preference==mBillingCycle){
			CycleEditorFragment.show(this);
			return true;
		}else if(preference==mDataWarning){
			BytesEditorFragment.show(this,false);
			return true;
		}else if(preference==mDataLimit){
			BytesEditorFragment.show(this,true);
			return true;
		}
		return super.onPreferenceTreeClick(preference);
	}
	
	@Override
	public boolean onPreferenceChange(Preference preference,Object newValue){
		if(mEnableDataLimit==preference){
			boolean enabled=(Boolean)newValue;
			if(enabled){
				ConfirmLimitFragment.show(this);
			}else{
				setPolicyLimitBytes(LIMIT_DISABLED);
			}
			return true;
		}
		return false;
	}
	
	@Override
	protected int getMetricsCategory(){
		return MetricsEvent.BILLING_CYCLE;
	}
	
	private void setPolicyLimitBytes(long limitBytes){
		services.mPolicyEditor.setPolicyLimitBytes(mNetworkTemplate,limitBytes);
		updatePrefs();
	}
	
	public static class BytesEditorFragment extends DialogFragment
			implements DialogInterface.OnClickListener{
		private static final String EXTRA_TEMPLATE="template";
		private static final String EXTRA_LIMIT="limit";
		private View mView;
		
		public static void show(BillingCycleSettings parent,boolean isLimit){
			if(!parent.isAdded())return;
			
			final Bundle args=new Bundle();
			args.putParcelable(EXTRA_TEMPLATE, parent.mNetworkTemplate);
			args.putBoolean(EXTRA_LIMIT, isLimit);
			
			final BytesEditorFragment dialog=new BytesEditorFragment();
			dialog.setArguments(args);
			dialog.setTargetFragment(parent, 0);
			dialog.show(parent.getFragmentManager(),TAG_WARNING_EDITOR);
		}
		
		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState){
			final Context context=getActivity();//Fragment里面的getActivity方法可以得到对应的Context
			
			final LayoutInflater DialogInflater=LayoutInflater.from(context);
			final boolean isLimit=getArguments().getBoolean(EXTRA_LIMIT);
			mView=DialogInflater.inflate(R.id.data_usage_bytes_editor, null,false);
			setupPicker((EditText)mView.findViewById(R.id.bytes),
					(Spinner)mView.findViewById(R.id.size_spinner));
			return new AlertDialog.Builder(context)
				.setTitle(isLimit?R.string.data_usage_limit_editor_title
						:R.string.data_usage_warning_editor_title)
						.setView(mView)
						.setPositiveButton(R.string.data_usage_cycle_editor_positive,this)
						.create();
		}
		
		private void setupPicker(EditText bytesPicker,Spinner type){
			final BillingCycleSettings target=(BillingCycleSettings)getTargetFragment();
			final NetworkPolicyEditor editor=target.services.mPolicyEditor;
			
			final NetworkTemplate template=getArguments().getParcelable(EXTRA_TEMPLATE);
			final boolean isLimit=getArguments().getBoolean(EXTRA_LIMIT);
			final long bytes=isLimit? editor.getPolicyLimitBytes(template):
				editor.getPolicyWarningBytes(template);
			final long limitDisabled=isLimit? LIMIT_DISABLED:WARNING_DISABLED;
			
			if(bytes>1.5f*GB_IN_BYTES){
				bytesPicker.setText(formatText(bytes/(float)GB_IN_BYTES));
				type.setSelection(1);
			}else{
				bytesPicker.setText(formatText(bytes/(float)MB_IN_BYTES));
				type.setSelection(0);
			}
		}
		
		private String formatText(float v){
			v=Math.round(v*100)/100f;
			//Math.round(float a);将参数加上0.5后返回与参数最近的整数
			//其实就是去小数部分取整数部分然后再加一
			return String.valueOf(v);//取float型变量的String类型
		}

		@Override
		public void onClick(DialogInterface arg0, int arg1) {
			// TODO Auto-generated method stub
			if(arg1!=DialogInterface.BUTTON_POSITIVE){
				return;
			}
			final BillingCycleSettings target=(BillingCycleSettings)getTargetFragment();
			final NetworkPolicyEditor editor=target.services.mPolicyEditor;
			
			final NetworkTemplate template=getArguments().getParcelable(EXTRA_TEMPLATE);
			final boolean isLimit=getArguments().getBoolean(EXTRA_LIMIT);
			EditText bytesField=(EditText)mView.findViewById(R.id.bytes);
			Spinner spinner=(Spinner)mView.findViewById(R.id.size_spinner);
			
			String bytesString=bytesField.getText().toString();
			if(bytesString.isEmpty()||bytesString.equals(".")){
				bytesString="0";
			}
			final long bytes=(long)(Float.valueOf(bytesString)
					*(spinner.getSelectedItemPosition()==0? MB_IN_BYTES:GB_IN_BYTES));
			if(isLimit){
				editor.setPolicyLimitBytes(template,bytes);
			}else{
				editor.setPolicyWarningBytes(template,bytes);
			}
			target.updatePrefs();
				
		}
	}
	
	
	public static class CycleEditorFragment extends DialogFragment implements
			DialogInterface.OnClickListener{
		private static final String EXTRA_TEMPLATE="template";
		private NumberPicker mCycleDayPicker;
		
		public static void show(BillingCycleSettings parent){
			if(!parent.isAdded()) return;
			final Bundle args=new Bundle();
			args.putParcelable(EXTRA_TEMPLATE, parent.mNetworkTemplate);
			
			final CycleEditorFragment dialog=new CycleEditorFragment();
			dialog.setArguments(args);
			//这个方法可以保存Fragment的相关信息,同样是在Fragment中通过getArguments获取保存的信息
			dialog.setTargetFragment(parent, 0);
			//这个方法可以传递parent给dialog对应的类CycleEditorFragment,我们可以在CycleEditorFragment中通过getTargetFragment()获取parent实例
			dialog.show(parent.getFragmentManager(), TAG_CYCLE_EDITOR);
			//dialog这个Fragment将会加入到parent.getFragmentManager()得到的FragmentManager中
		}
		
		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			final Context context=getActivity();//Fragment中获取相关活动的方法
			final BillingCycleSettings target=(BillingCycleSettings)getTargetFragment();
			final NetworkPolicyEditor editor=target.services.mPolicyEditor;
			
			final AlertDialog.Builder builder=new AlertDialog.Builder(context);
			final LayoutInflater dialogInflater=LayoutInflater.from(builder.getContext());
			
			final View view=dialogInflater.inflate(R.layout.data_usage_cycle_editor, null,false);
			mCycleDayPicker=view.findViewById(R.id.cycle_day);
			
			final NetWorkTemplate template=getArguments().getParcelable(EXTRA_TEMPLATE);
			//在这里获取上一个Fragment保存的信息
			final int cycleDay=editor.getPolicyCycleDay(template);
			
			final int cycleDayValue=cycleDay;
			if(savedInstanceState!=null){
				cycleDayValue=savedInstanceState.getInt("cycleDayValue");
			}
			mCycleDayPicker.setMinValue(1);
			mCycleDayPicker.setMaxValue(31);
			mCycleDayPicker.setValue(cycleDayValue);
			mCycleDayPicker.setWrapSelectorWheel(true);
			return builder.setTitle(R.string.data_usage_cycle_editor_title)
					.setView(view)
					.setPositiveButton(R.string.data_usage_cycle_editor_positive,this)
					.create();
		}
		
		@Override
		public void onSaveInstanceState(Bundle outState) {
			// TODO Auto-generated method stub
			super.onSaveInstanceState(outState);
			outState.putInt("cycleDayValue", mCycleDayPicker.getValue());
		}
		
		@Override
		public void onClick(DialogInterface arg0, int arg1) {
			final NetworkTemplate template=getArguments().getParcelable(EXTRA_TEMPLATE);
			final BillingCycleSettings target=(BillingCycleSettings)getTargetFragment();
			//获取之前传递给CycleEditorFragment的BillingCycleSettings类的对象
			final NetworPolicyEditor editor=target.services.mPolicyEditor;
			
			mCycleDayPicker.clearFocus();
			
			final int cycleDay=mCycleDayPicker.getValue();
			final String cycleTimezone=new Time().timezone;
			editor.setPolicyCycleDay(template,cycleDay,cycleTimezone);
			target.updatePrefs();	
		}
	}
	
	public static class ConfirmLimitFragment extends DialogFragment implements
		DialogInterface.OnClickListener{
		private static final String EXTRA_MESSAGE="message";
		private static final String EXTRA_LIMIT_BYTES="limitBytes";
		public static final float FLOAT=1.2f;
		
		public static void show(BillingCycleSettings parent){
			if(!parent.isAdded()) return;
			
			final NetworkPolicy policy=parent.services.mPolicyEditor
					.getPolicy(parent.mNetworkTemplate);
			if(policy==null)return;
			
			final Resources res=parent.getResources();
			final CharSequence message;
			final long minLimitBytes=(long)(policy.warningBytes*FLOAT);
			final long limitBytes;
			
			message=res.getString(R.string.data_usage_limit_dialog_mobile);
			limitBytes=Math.max(5*GB_IN_BYTES, minLimitBytes);
			
			final Bundle args=new Bundle();
			args.putCharSequence(EXTRA_MESSAGE, message);
			args.putLong(EXTRA_LIMIT_BYTES, limitBytes);
			
			final ConfirmLimitFragment dialog=new ConfirmLimitFragment();
			dialog.setArguments(args);
			dialog.setTargetFragment(parent, 0);
			dialog.show(parent.getFragmentManager(), TAG_CONFIRM_LIMIT);
		}
		
		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			final Context context=getActivity();
			
			final CharSequence message=getArguments().getCharSequence(EXTRA_MESSAGE);
			
			return new AlertDialog.Builder(context)
				.setTitle(R.string.data_usage_limit_dialog_title)
				.setMessage(message)
				.setPositiveButton(android.R.string.ok,this)
				.setNegativeButton(android.R.string.cancel,this)
				.create();
		}
		
		@Override
		public void onClick(DialogInterface dialog,int which){
			final BillingCycleSettings target=(BillingCycleSettings)getTargetFragment();
			if(which!=DialogInterface.BUTTON_POSITIVE){
				if(target!=null){
					target.updatePrefs();
				}
				return;
			}
			final long limitBytes=getArgument().getLong(EXTRA_LIMIT_BYTES);
			
			if(target!=null){
				target.setPolicyLimitBytes(limitBytes);
			}
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值