ListPreference,DialogPreference、PreferenceActivity、RadioButton、RadioGroup、RingtonePreference、TextView、View、ViewGroup
package com.hyz; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.widget.CompoundButton; import android.widget.RadioButton; import android.widget.CompoundButton.OnCheckedChangeListener; public class TypedefRadioButton extends RadioButton implements OnCheckedChangeListener { private String mValue; public String getValue() { return this.mValue; } public void setValue(String value) { this.mValue = value; } public TypedefRadioButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public TypedefRadioButton(Context context, AttributeSet attrs) { super(context, attrs); try { /** * TypedArray其实就是一个存放资源的Array, * 首先从上下文中获取到R.styleable.RadioButton这个属性资源的资源数组。 * attrs是构造函数传进来,应该就是对应attrs.xml文件。 * a.getString(R.styleable.RadioButton_value); * 这句代码就是获取attrs.xml中定义的属性,并将这个属性的值传给本控件的mValue.最后, * 返回一个绑定结束的信号给资源:a.recycle();绑定结束。 */ TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.RadioButton); this.mValue = a.getString(R.styleable.RadioButton_value); a.recycle(); } catch (Exception e) { e.printStackTrace(); } setOnCheckedChangeListener(this); } public TypedefRadioButton(Context context) { super(context); // TODO Auto-generated constructor stub } public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { TypedefRadioGroup group = (TypedefRadioGroup) getParent(); group.setTheValue(this.getValue()); } }
package com.hyz;import android.content.Context;import android.preference.DialogPreference;import android.util.AttributeSet;import android.view.View;import android.widget.TextView;import android.widget.Toast;public class TypedefDialogPreference extends DialogPreference{private int dialogMessage ;public TypedefDialogPreference(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}//程序首先执行此函数public TypedefDialogPreference(Context context, AttributeSet attrs){super(context, attrs);//通过此句得到布局里的自定义变量dialogMessage里的值,括号里第2个参数其实//是一个resId,要得到其字符串值,在布局里只能用dialogMessage = "@string/dialogMessage"形式,//不能用dialogMessage = "字符串"形式。否则得到的是R.string.empty默认值。dialogMessage = attrs.getAttributeResourceValue(null, "dialogMessage", R.string.empty);}//这个函数是为对话框中引用的其它布局而起作用的@Overrideprotected void onBindDialogView(View view)//view 其实代表的就是slider_dialog.xml{TextView tv1 = (TextView)view.findViewById(R.id.slider_message1);tv1.setText("你好呀^_^");TextView tv2 = (TextView)view.findViewById(R.id.slider_message2);tv2.setText(dialogMessage);}@Overrideprotected void onDialogClosed(boolean positiveResult) {super.onDialogClosed(positiveResult);if(positiveResult)Toast.makeText(getContext(), "点击了对话框的确定按钮", Toast.LENGTH_LONG).show();} }
package com.hyz; import android.app.AlertDialog.Builder; import android.content.Context; import android.content.DialogInterface; import android.preference.ListPreference; import android.util.AttributeSet; import android.util.Log; import android.widget.Toast; public class TypedefListPreference extends ListPreference { //用来保存ListPreference中的列表项的是否选择值 private boolean[] checkedItems; CharSequence[] entries ;//ListPreference.getEntries(),显示 在列表中的数据 CharSequence[] entryValues;//显示在summary里的值 public TypedefListPreference(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public TypedefListPreference(Context context) { super(context); // TODO Auto-generated constructor stub } //点击ok或cancel后触发的事件,自定义视图事件 @Override protected void onDialogClosed(boolean positiveResult) { if(positiveResult) { CharSequence[] entryValues = getEntryValues(); StringBuilder str = new StringBuilder(); for(int i = 0 ; i < 7 ; i++) { if(checkedItems[i]) { str.append(entryValues[i]); } } setSummary(str); } } /*此函数复写后,如果函数体为空,则ListPreference对话框内容为空 * 删除此函数的话,系统将自动加载entryValues和entries为对话框的内容 * 因为为自定义的ListPreference,所以复写下面的方法为的就是可以自定义ListPreference对话框的显示内容 */ @Override protected void onPrepareDialogBuilder(Builder builder) { checkedItems = new boolean[7]; CharSequence[] entries = getEntries(); CharSequence[] entryValues = getEntryValues(); //删除preference.xml中的entries、entryValues将显示Toast if (entries == null || entryValues == null) { Toast.makeText(getContext(), "getEntries()或getEntryValues()为空", Toast.LENGTH_LONG).show(); } builder.setMultiChoiceItems(entries, checkedItems, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { checkedItems[which] = isChecked; } }); } }
public class TypedefPreferenceActivity extends PreferenceActivity { private TypedefDialogPreference TDialogPreference; private TypedefListPreference TListPreference; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preference); } }
package com.hyz; import android.content.Context; import android.util.AttributeSet; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; public class TypedefRadioGroup extends RadioGroup implements OnCheckedChangeListener { private String mValue; public TypedefRadioGroup(Context context, AttributeSet attrs) { super(context, attrs); this.setOnCheckedChangeListener(this); } public TypedefRadioGroup(Context context) { super(context); this.setOnCheckedChangeListener(this); } // 设置子控件的值 private void setChildValue() { int n = this.getChildCount(); for(int i=0;i<n;i++) { TypedefRadioButton radio = (TypedefRadioButton)this.getChildAt(i); if(radio.getValue().equals(this.mValue)) { radio.setChecked(false); } else { radio.setChecked(true); } } } // 获取子类的值 private void getChildValue() { int n = this.getChildCount(); for(int i=0;i<n;i++){ TypedefRadioButton radio = (TypedefRadioButton)this.getChildAt(i); if(radio.isChecked()){ this.mValue=radio.getValue(); } } } public void setTheValue(String value) { this.mValue = value; } public String getTheValue(){ getChildValue(); return this.mValue; } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { setChildValue(); } }
package com.hyz; import android.content.Context; import android.net.Uri; import android.preference.RingtonePreference; import android.util.AttributeSet; import android.content.Intent; import android.media.RingtoneManager; import android.util.Log; public class TypedefRingtonePreference extends RingtonePreference { private boolean mShowDefault;//是否在铃声列表中显示默认铃声选项,否则隐藏 private Uri mUri; public TypedefRingtonePreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); Log.i("cd", "a"); } //程序首先调用这个函数,其次onRestoreRingtone,再次onPrepareRingtonePickerIntent,最后onSaveRingtone public TypedefRingtonePreference(Context context, AttributeSet attrs) { super(context, attrs); //preference.xml里android:showDefault="true"设置显示“默认铃声”项,而下一句又可以将它隐藏 mShowDefault = getShowDefault(); //是否在铃声列表中显示默认铃声选项,否则隐藏 //getRingtoneType(); //getShowSilent();是否在铃声列表中显示静音选项,否则隐藏 Log.i("cd", "b"); } public TypedefRingtonePreference(Context context) { super(context); // TODO Auto-generated constructor stub Log.i("cd", "c"); } //此函数主要用来显示或隐藏铃声列表中某些铃声项 @Override protected void onPrepareRingtonePickerIntent(Intent ringtonePickerIntent) { // TODO Auto-generated method stub super.onPrepareRingtonePickerIntent(ringtonePickerIntent); Log.i("cd", "onPrepareRingtonePickerIntent"); //mShowDefault若为false,从列表隐藏”默认铃声“选项 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, mShowDefault); //虽然android:showSilent="false",但下一句将”静音“选项显示在列表中 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT,true); // if(mShowDefault) // { // Uri uri = Uri.parse(Settings.System.DEFAULT_RINGTONE_URI.toString()); // ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, uri); // } } //此函数得到所有铃声项及上次所选铃声项 @Override protected Uri onRestoreRingtone() { // TODO Auto-generated method stub Log.i("cd", "onRestoreRingtone"); //此句话能够得到上一次设置的铃声列表以及上次所选铃声项 return RingtoneManager.getActualDefaultRingtoneUri(getContext(), getRingtoneType()); } //点击确定按钮后将保存铃声路径至自定义变量 @Override protected void onSaveRingtone(Uri ringtoneUri) {//注意这个方法 他是实现铃声设置的核心方法 Log.i("cd", "onSaveRingtone"); if(ringtoneUri!=null) { mUri = ringtoneUri; } //注意添加权限"android.permission.WRITE_SETTINGS" //保存所选铃声 //第一个参数表示上下文、第二个参数表示设置的铃声状态,第三个表示当前的歌曲uri RingtoneManager.setActualDefaultRingtoneUri(getContext(), getRingtoneType(), ringtoneUri); } }
package com.hyz; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; import android.widget.Toast; public class TypedefTextView extends TextView { public TypedefTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } /* * 当手指从按钮抬起,ACTION_UP 取消,ACTION_CANCEL 手指移出按钮,ACTION_OUTSIDE 另外,要返回false,因为返回true,系统将不会调用drawable/button.xml的效果, 因为true表示自己已经处理了onTouche事件,不需要别的逻辑再处理了。 */ public TypedefTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); // TODO Auto-generated constructor stub this.setOnTouchListener(new OnTouchListener(){ public boolean onTouch(View v, MotionEvent event) { if (event.getAction()==MotionEvent.ACTION_CANCEL ||event.getAction()==MotionEvent.ACTION_UP ||event.getAction()==MotionEvent.ACTION_OUTSIDE) { Toast.makeText(getContext(), "touch", Toast.LENGTH_LONG).show(); } return false; } }); } public TypedefTextView(Context context) { super(context); // TODO Auto-generated constructor stub } }
package com.hyz; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.util.AttributeSet; import android.view.View; //这个出现在main.xml里 /** * 这个是自定义的TextView. * 至少需要重载构造方法和onDraw方法 * 对于自定义的View如果没有自己独特的属性,可以直接在xml文件中使用就可以了 * 如果含有自己独特的属性,那么就需要在构造函数中获取属性文件attrs.xml中自定义属性的名称 * 并根据需要设定默认值,放在在xml文件中没有定义。 * 如果使用自定义属性,那么在应用xml文件中需要加上新的schemas, * 比如这里是xmlns:my="http://schemas.android.com/apk/res/com.hyz" * 其中xmlns后的“my”是自定义的属性的前缀,res后的是我们自定义View所在的包 */ public class TypedefView extends View { Paint mPaint; //画笔,包含了画几何图形、文本等的样式和颜色信息 public TypedefView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public TypedefView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); //TypedArray是一个用来存放由context.obtainStyledAttributes获得的属性的数组 //在使用完成后,一定要调用recycle方法 //属性的名称是styleable中的名称+“_”+属性名称 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyView); int textColor = array.getColor(R.styleable.MyView_textColor, 0XFF00FF00); //提供默认值,放置未指定 float textSize = array.getDimension(R.styleable.MyView_textSize, 36); mPaint.setColor(textColor); mPaint.setTextSize(textSize); array.recycle(); //一定要调用,否则这次的设定会对下次的使用造成影响 } public TypedefView(Context context) { super(context); // TODO Auto-generated constructor stub } public void onDraw(Canvas canvas){ super.onDraw(canvas); //Canvas中含有很多画图的接口,利用这些接口,我们可以画出我们想要的图形 //mPaint = new Paint(); //mPaint.setColor(Color.RED); mPaint.setStyle(Style.FILL); //设置填充 canvas.drawRect(10, 10, 100, 100, mPaint); //绘制矩形 mPaint.setColor(Color.BLUE); canvas.drawText("我是被画出来的", 10, 120, mPaint); } }
package com.hyz; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; public class TypedefViewGroup extends ViewGroup { @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int count = this.getChildCount(); for(int i = 0;i < count;i++) { View child = this.getChildAt(i); child.setVisibility(View.VISIBLE); child.measure(r-l, b-t); int x = l; int y = t;// ??? 心中疑惑:我认为我只要在这里调用child的layout(int,int,int,int)方法给出它的位置和宽高就可以了//如果child本身是一个ViewGroup的话它是否应该自己去管理它本身内部的child的位置和宽度呢??? child.layout(x,y,x + getWidth(),y + getHeight()); } } public TypedefViewGroup(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public TypedefViewGroup(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public TypedefViewGroup(Context context) { super(context); // TODO Auto-generated constructor stub } }
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <com.hyz.TypedefListPreference android:key="TListPreference" android:title="TypedefListPreference" android:dialogTitle="对话框标题" android:summary="Summary" android:dialogIcon="@drawable/hippo" android:positiveButtonText="OK" android:entries="@array/days_of_week" android:entryValues="@array/days_of_week_short"/> <com.hyz.TypedefDialogPreference android:key="TDialogPreferecnce" android:title="TypedefDialogPreference" android:dialogTitle="对话框标题" android:dialogLayout="@layout/slider_dialog" dialogMessage = "@string/dialogMessage"/> <com.hyz.TypedefRingtonePreference android:key="TRingtonePreference" android:title="TypedefRingtonePreference" android:ringtoneType="alarm" android:showDefault="true" android:showSilent="false"/> </PreferenceScreen>
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, ddd!</string> <string name="app_name">自定义布局</string> <string-array name="days_of_week"> <item>"周一"</item> <item>"周二"</item> <item>"周三"</item> <item>"周四"</item> <item>"周五"</item> <item>"周六"</item> <item>"周日"</item> </string-array> <string-array name="days_of_week_short"> <item>"一"</item> <item>"二"</item> <item>"三"</item> <item>"四"</item> <item>"五"</item> <item>"六"</item> <item>"日"</item> </string-array> <string name="empty">strings.xml</string> <string name="dialogMessage">在布局里自定义的变量</string> <style name="CustomWindowTitleBackground"> <item name="android:background">#aa0000</item> </style> <!-- 自定义标题栏样式,在程序的android manifest.xml中对应activity中添加属性 android:theme = "@style/test" 就可以了 --> <style name="test" parent="android:Theme"> <item name="android:windowTitleSize">50dp</item> <item name="android:windowTitleBackgroundStyle">@style/CustomWindowTitleBackground</item> </style> <declare-styleable name="RadioButton"><!-- 控件名称--> <attr name="value" format="string"/><!-- 属性名称,类型--> </declare-styleable> <declare-styleable name="MyView"> <attr name="textColor" format="color"/> <attr name="textSize" format="dimension"/> </declare-styleable> </resources>
TypedefViewTest
最新推荐文章于 2025-05-08 16:36:12 发布