关于Android里自定义属性的使用网上已经有很多介绍了,比如:
在Button组件里有android:onClick属性,其值是点击Button时触发的方法的名称。我这里想说的就是添加这种属性方法的方法。
比如我们现在有这样一个自定义组件:
它是由一个TextView,一个SeekBar,再加一个TextView组成:
//aq_mic_seekbar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mic_seekbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center"
android:background="#ff0000"
>
<TextView
android:id="@+id/mic_seekbar_title"
android:layout_width="100dp"
android:layout_height="30dp"
android:hint="title"
android:gravity="center"
android:background="#00ff00"
/>
<SeekBar
android:id="@+id/mic_seekbar_seekbar"
android:layout_width="200dp"
android:layout_height="30dp"
android:max="100"
android:progress="50"
/>
<TextView
android:id="@+id/mic_seekbar_value"
android:layout_width="50dp"
android:layout_height="30dp"
android:hint="value"
android:gravity="center"
android:background="#00ff00"
/>
</LinearLayout>
//AQmic_seekbar.java
public class AQmic_seekbar extends LinearLayout {
public AQmic_seekbar(Context context) {
this(context,null);
// TODO Auto-generated constructor stub
}
public AQmic_seekbar(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
LayoutInflater.from(context).inflate(R.layout.aq_mic_seekbar, this,true);
}
}
//activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<com.example.aqmic.AQmic_seekbar
android:layout_width="500dp"
android:layout_height="50dp" />
</RelativeLayout>
//MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
现在我们为这个组件添加一个onSeekBarChange属性,其值是当组件里的SeekBar改变时触发的方法的名称。
//attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="AQmic_seekbar">
<attr name="onSeekBarChange" format="string" />
</declare-styleable>
</resources>
然后在我们的组件类文件里对该属性进行处理,这也是最关键的地方:
//AQmic_seekbar.xml
public class AQmic_seekbar extends LinearLayout {
Method mMethod;
SeekBar mSeekBar;
Context mContext;
public AQmic_seekbar(Context context) {
this(context,null);
// TODO Auto-generated constructor stub
}
public AQmic_seekbar(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
LayoutInflater.from(context).inflate(R.layout.aq_mic_seekbar, this,true);
mSeekBar = (SeekBar)findViewById(R.id.mic_seekbar_seekbar);
mContext = context;
//获取onSeekBarChange属性的值
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.AQmic_seekbar);
CharSequence onSeekBarChange = ta.getText(R.styleable.AQmic_seekbar_onSeekBarChange);
try {
//根据方法名获取方法
mMethod = context.getClass().getMethod((String)onSeekBarChange, View.class);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
try {
//调用方法
mMethod.invoke(mContext, seekBar);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void onStartTrackingTouch(SeekBar seekBar) {}
public void onStopTrackingTouch(SeekBar seekBar) {}
});
ta.recycle();
}
}
最后修改activity_main.xml,为我们的组件添加该属性,并在主Activity文件里实现该方法:
//activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myspace="http://schemas.android.com/apk/res/com.example.aqmic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<com.example.aqmic.AQmic_seekbar
android:id="@+id/mySeekBar"
android:layout_width="500dp"
android:layout_height="50dp"
myspace:onSeekBarChange="onMySeekBarChange"
/>
</RelativeLayout>
//MainActivity.java
public class MainActivity extends Activity {
SeekBar mSeekBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onMySeekBarChange(View view)
{
mSeekBar = (SeekBar)view;
mSeekBar.setProgress(mSeekBar.getMax());
}
}
这样当SeekBar组件进度值发生改变时,其进度值就会变为最大了。