TypedefViewTest
16lz
2021-01-26
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:fsms="http://schemas.android.com/apk/res/com.hyz" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.hyz.TypedefRadioGroup android:id="@+id/radPayOrNot" android:layout_width="wrap_content" android:layout_height="wrap_content" > <com.hyz.TypedefRadioButton android:id="@+id/isPayDepositTrue" fsms:value="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="yes" android:textSize="18sp"/> <com.hyz.TypedefRadioButton android:id="@+id/isPayDepositFalse" fsms:value="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="no" android:textSize="18sp" /> <com.hyz.TypedefRadioButton android:id="@+id/isPayDepositFalse" fsms:value="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="A" android:textSize="18sp" /> <com.hyz.TypedefRadioButton android:id="@+id/isPayDepositFalse" fsms:value="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="B" android:textSize="18sp" /> </com.hyz.TypedefRadioGroup></LinearLayout><!-- 命名空间为fsms.路径是http://schemas.android.com/apk/res/这一部分是不变的,后面接的是R的路径:rog.kandy.R。然后在自定义控件的xml描述中就可以这样使用fsms:value="true"。这样就实现了自定义控件的初始化赋值 -->
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.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(); }}
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#aa0000"> <LinearLayout android:layout_width="fill_parent" android:layout_height="10dip" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="40dip"> <com.hyz.TypedefTextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:text="电影" android:gravity="center_vertical|center_horizontal" android:background="@drawable/button" android:focusable="true" android:clickable="true"/> <View android:layout_width="2px" android:layout_height="fill_parent" android:background="#ffffffff" /> <com.hyz.TypedefTextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:layout_weight="1" android:text="电视" android:gravity="center_vertical|center_horizontal" android:background="@drawable/button" android:focusable="true" /> <View android:layout_width="2px" android:layout_height="fill_parent" android:background="#ffffffff" /> <com.hyz.TypedefTextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:layout_weight="1" android:text="明星" android:gravity="center_vertical|center_horizontal" android:background="@drawable/button" android:focusable="true" /> </LinearLayout> </LinearLayout>
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 stubthis.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}}
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:my="http://schemas.android.com/apk/res/com.hyz" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.hyz.TypedefView android:layout_width="fill_parent" android:layout_height="wrap_content" my:textColor="#FFFFFFFF" my:textSize="22dp" /> </LinearLayout> <!-- * 如果使用自定义属性,那么在应用xml文件中需要加上新的schemas, * 比如这里是xmlns:my="http://schemas.android.com/apk/res/com.hyz" * 其中xmlns后的“my”是自定义的属性的前缀,res后的是我们自定义View所在的包 -->
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.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,最后onSaveRingtonepublic 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 stubLog.i("cd", "c");}//此函数主要用来显示或隐藏铃声列表中某些铃声项@Overrideprotected void onPrepareRingtonePickerIntent(Intent ringtonePickerIntent) {// TODO Auto-generated method stubsuper.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);//} }//此函数得到所有铃声项及上次所选铃声项@Overrideprotected Uri onRestoreRingtone() {// TODO Auto-generated method stubLog.i("cd", "onRestoreRingtone");//此句话能够得到上一次设置的铃声列表以及上次所选铃声项return RingtoneManager.getActualDefaultRingtoneUri(getContext(), getRingtoneType());}//点击确定按钮后将保存铃声路径至自定义变量@Overrideprotected 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.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后触发的事件,自定义视图事件@Overrideprotected 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对话框的显示内容 */@Overrideprotected 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() {@Overridepublic void onClick(DialogInterface dialog, int which, boolean isChecked) {checkedItems[which] = isChecked;} });} }
更多相关文章
- 选择型控件
- grant-uri-permission
- 【Android(安卓)Studio】Gradle配置及问题解决
- Android之Init进程
- 常用对话框部分属性
- MPAndroidChart的具体属性方法
- The builder launch configuration could not be found
- Animation Resources
- android:ListView:convertView.setTag()来设置数据