关于自定义Preference内置控件及PreferenceFragment笔记

  1. 我们知道系统Preference提供的控件并不多,只有CheckBoxPreference,ListPreference,EditTextPreference,RingtonePreference等为数不多的控件,有时候并不能满足我们的需求.这时候我们就需要自定义,比如自定义一个SeekBar用来调节音量什么的.这里我就不介绍如何自定义包含SeekBar的Preference,大家可以查看Android自定义SeekBarPreference.
这里需要提及的是,我们自定的这个控件,往往需要和Activity或者Service通信,这时候该怎么操作呢?
我们同样还是以SeekBarPreference为例.我们都知道,当滑动SeekBar的时候,系统会回调onProgressChanged方法.假如我们需要在onProgressChanged中与 Activity/Fragment/Service通信.这时候就需要定义一个接口在其中声明我们需要用到的方法.然后声明一个函数,将接口的引用作为参数提供给Activity/Fragment/
Service调用.
public class VolumeSeekBarPreferences extends DialogPreference implements OnSeekBarChangeListener {
	private seekBarCallBack back;

	....

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {
		// TODO Auto-generated method stub
			....
		back.setSeekBarVolume(mCurrentValue);
			....

	}
	
	....

	public interface seekBarCallBack{
		public void setSeekBarVolume(int volume);
	}
	
	public void setSeekbarListener(seekBarCallBack barCallBack){
		back = barCallBack;
	}
}

然后,在Activity/Fragment/Service中通过实现控件Preference中的传递接口引用的函数.

public class MyPreferenceFragment extends PreferenceFragment implements
		OnPreferenceClickListener, OnPreferenceChangeListener {

	private VolumeSeekBarPreferences seekBarPreferences;

				.....

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.layout.preference_setting);
		//VolumeSeekBarPreferences为我们自定义的Preference控件
		seekBarPreferences = (VolumeSeekBarPreferences) findPreference("seekBarPreference");
		seekBarPreferences.setSeekbarListener(new seekBarCallBack() {

			@Override
			public void setSeekBarVolume(int volume) {
				// TODO Auto-generated method stub
				//在这里实现通信
			}
		});

	}

				.....


}

2.Fragment如何调用Service的方法?
Fragment和Activity的通信大家都知道,可以通过在Fragment声明接口,然后在Activity中implements这个接口
	public class MyPreferenceFragment extends PreferenceFragment implements
		OnPreferenceClickListener, OnPreferenceChangeListener{
	private Activity context;
		.....
	
	@Override
	public void onAttach(Activity activity) {
		// TODO Auto-generated method stub
		super.onAttach(activity);
		context = activity;
		try {
			callbackSetting = (CallbackSetting) context;
		} catch (Exception e) {
			// TODO: handle exception
		}

	}
			.....

	/*
	 * 利用回调函数,让IntentActivity调用Service的方法来实现Fragment间接调用Service的方法
	 */
	public interface CallbackSetting {
		public int getVolume();

		public void setVolume(int volume);
		
		public void setRemoteModel(boolean flag);
		
		public void readModelInfo();
		
	}

			......

	@Override
	public boolean onPreferenceChange(Preference preference, Object newValue) {
		// TODO Auto-generated method stub
		if(preference == checkBoxRemote){
			if((Boolean)newValue){
				callbackSetting.setRemoteModel(true);
			}else {
				callbackSetting.setRemoteModel(false);
			}
			
		}
		return true;
	}

			......
}
Activity中:
public class IntentActivity extends Activity implements ServiceConnection, CallbackSetting{
			......

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.empty_layout);

		Intent settingIntent = new Intent("com.example.RadioService");
		this.bindService(settingIntent, this, BIND_AUTO_CREATE);
	}

			.......

	@Override
	public void setRemoteModel(boolean flag) {
		// TODO Auto-generated method stub
		if(flag){
			radioService.setRemote(1);
		}else {
			radioService.setRemote(0);
		}
	}
			
			......
}
因为Activity可以通过bindService绑定Service并调用Service中的方法.所以这里,Activity只是通过实现Fragment的接口来充当中介.

3.Fragment中是可以发送和接收Broadcast的
 
		......
@Override  
    public void onAttach(Activity activity) {  
         
        /** 注册广播 */  
        receiveBroadCast = new ReceiveBroadCast();  
        IntentFilter filter = new IntentFilter();  
        filter.addAction("com.gasFragment");    //只有持有相同的action的接受者才能接收此广播  
        activity.registerReceiver(receiveBroadCast, filter);  
        super.onAttach(activity);  
    }  
		......

 class ReceiveBroadCast extends BroadcastReceiver  
        {  
                @Override  
                public void onReceive(Context context, Intent intent)  
                {  
                    //得到广播中得到的数据,并显示出来  
                    String gasname = intent.getExtras().getString("gasName");  
                    String address = intent.getExtras().getString("address");  
                     
                    gasadderss.setText("地址:\n  "+address);  
                    gasName.setText(gasname);  
                }  
        }  

     /**
      *注销广播
      * */  
     @Override  
     public void onDestroyView() {  
        getActivity().unregisterReceiver(receiveBroadCast);  
        super.onDestroyView();  
     }  

		......

4.如何在其他的Activity/Service中获取Preference保存的值
在Activity/Service调用以下代码就可以获取Preference保存的值,很简单~
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 
mRemote = prefs.getBoolean("checkbox_remote_preference", true);//两个参数,一个是Preference控件的android:key属性,
					     			//另一个是取不到值时的默认值 

5.Preference中 onPreferenceClick  onPreferenceTreeClick  onPreferenceChange调用顺序:
当一个Preference控件实现这两个接口时,当被点击或者值发生改变时,触发方法是如何执行的呢?事实上,
它的触发规则如下:
      1 先调用onPreferenceClick()方法,如果该方法返回true,则不再调用onPreferenceTreeClick方法 ;
     
    如果onPreferenceClick方法返回false,则继续调用onPreferenceTreeClick方法。
     
   2 onPreferenceChange的方法独立与其他两种方法的运行。也就是说,它总是会运行。

补充:1 点击某个Preference控件后,会先回调onPreferenceChange()方法,即是否保存值,然后再回调onPreferenceClick以及onPreferenceTreeClick()方法,
        因此在onPreferenceClick/onPreferenceTreeClick方法中我们得到的控件值就是最新的Preference控件值。
     
         2 如果是自定义的Preference控件,且点击Preference列表后出现新窗口那么该控件会直接调用onPreferenceTreeClick方法,而不调用onPreferenceClick,
因为onPreferenceClick中没有PreferenceScreen参数



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值