TypedefViewTest

 
<?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 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
	}
	


}

<?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,最后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.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;
					}
                   
                });
	}
    
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章