本文总结TextView及其子类的一些用法和性质
1、用TextView设置滚动文本,获取宽度及字数
1)创建一个继承TextView的类,覆写isFocused方法。在XML文件给TextView增加ellipsize="marquee"的属性
public class MarqueeTextView extends TextView {
public MarqueeTextView(Context context) {
super(context);
}
public MarqueeTextView(Context context,AttributeSet as){
super(context, as);
}
public MarqueeTextView(Context context,AttributeSet as,int defStyle){
super(context, as, defStyle);
}
@Override
@ExportedProperty(category = "focus")
public boolean isFocused() {
return true;
}
}
<com.me.spinner.MarqueeTextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:marqueeRepeatLimit="marquee_forever"
android:background="@android:color/transparent"/>
2)获取字符长度,区分普通字符和汉字
private int getCharLength(String str){
if(TextUtils.isEmpty(str)){
return 0;
}
int len=0;
for(int i=0;i<str.length();i++){
Character.UnicodeBlock ub = Character.UnicodeBlock.of(str.charAt(i));
if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
len += 2;
}else{
len += 1;
}
}
return len;
}
private String getShortChars(String str){
if(TextUtils.isEmpty(str)){
return str;
}
int len=0;
for(int i=0;i<str.length();i++){
Character.UnicodeBlock ub = Character.UnicodeBlock.of(str.charAt(i));
//汉字取2普通字符取1
if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
len += 2;
}else{
len += 1;
}
if(len>3){
return str.substring(0, i);
}
}
return str;
}
还有些方法参考:getBytes(), length(), textView.getPaint().measureText(""),
getMeasuredWidth(), getWidth(), getTextSize()等
TextView字数过长默认截断并末尾显示"...",设置android:ellipsize="none"会取消省略号,默认值为“end”
2、一些按钮实现
1)示例代码
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//TextView子类
Button button = (Button) findViewById(R.id.v_button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.println(Log.VERBOSE, TAG, "Button");
}
});
//ImageView子类
ImageButton imageButton = (ImageButton) findViewById(R.id.imageButton);
imageButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.println(Log.DEBUG, TAG, "ImageButton");
}
});
//CompoundButton(extends Button implements Checkable)子类
Switch mSwitch = (Switch) findViewById(R.id.v_switch);
mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
Log.println(Log.INFO, TAG, "已打开");
}else{
Log.println(Log.INFO, TAG, "已关闭");
}
}
});
ToggleButton toggleButton = (ToggleButton) findViewById(R.id.v_togglebutton);
toggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
Log.w(TAG, "已打开");//Log.WARN
}else{
Log.w(TAG, "已关闭");
}
}
});
CheckBox checkBox = (CheckBox) findViewById(R.id.checkBox);
checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
Log.e(TAG, "已打开");//Log.ERROR
}else{
Log.e(TAG, "已关闭");
}
}
});
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radioGroup);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.radioButton1:
Log.wtf(TAG, "radioButton1");//Log.ASSERT
break;
case R.id.radioButton2:
Log.wtf(TAG, "radioButton2");
}
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/v_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"/>
<ImageButton
android:id="@+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"/>
<Switch
android:id="@+id/v_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Switch"
android:textOn="On"
android:textOff="Off"/>
<ToggleButton
android:id="@+id/v_togglebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="On"
android:textOff="Off"/>
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox"/>
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radioButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton1"/>
<RadioButton
android:id="@+id/radioButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton2"/>
</RadioGroup>
</LinearLayout>
2)分析
Button继承自TextView,继承了其android:text="Button"属性。ImageButton继承自ImageView,继承了其android:src="@drawable/ic_launcher"属性。
Switch、ToggleButton、CheckBox、RadioButton继承自CompoundButton,通过设置CompoundButton.OnCheckedChangeListener来监听check状态。
CompoundButton继承Button类、实现Checkable接口,是不含抽象方法的抽象类。
RadioButton配合RadioGroup使用。RadioGroup设置RadioGroup.OnCheckedChangeListener来监听单选按钮选择状态的变化。
3、一些小技巧
1)给EditText设置错误提示
/*Sets the right-hand compound drawable of the TextView to the "error" icon
and sets an error message that will be displayed in a popup when the TextView has focus*/
editText.setError("尖叫");
2)将TextView文本变成可跳转的链接
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:text="http://www.baidu.com"/>
4、android圆角按钮的设置
1)首先在res/drawable目录下创建selector_rectangle.xml文件,在其中设置圆角的半径及背景色:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<gradient
android:startColor="@android:color/white"
android:endColor="@android:color/black"
android:type="linear"
android:angle="0"/>
<stroke
android:width="1px"
android:color="@android:color/black"/>
<solid android:color="@color/yellow"/>
<corners android:radius="4dp"/>
</shape>
</item>
<item >
<shape android:shape="rectangle">
<solid android:color="@color/white"/>
<corners android:radius="4dip"/>
</shape>
</item>
</selector>
其中item标签的state_pressed属性用于区分是否摁下,gradient设置背景色为渐变色,stroke设置边框。
2)然后在布局文件的Button标签background属性设置此selector:<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/knowledge_btn_cp"
android:drawableTop="@drawable/knowledge_cp"
android:background="@drawable/selector_rectangle"
android:onClick="onClick"/>
5、自定义TextView
1、定义一个继承TextView的类
public class MyTextView extends TextView {
private Paint marginPaint;
private Paint linePaint;
private int paperColor;
private float margin;
public MyTextView(Context context){
this(context, null);
}
public MyTextView(Context context,AttributeSet as){//系统调用此构造器
this(context, as, android.R.attr.textViewStyle);
}
public MyTextView(Context context,AttributeSet as,int defStyle){
super(context, as, defStyle);
init();
}
@Override
protected void onDraw(Canvas canvas) {
//绘制背景
canvas.drawColor(paperColor);
//绘制左边线
canvas.drawLine(0, 0, 0, getMeasuredHeight(), linePaint);
//绘制底线
canvas.drawLine(0, getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight(), linePaint);
//绘制中间竖线
canvas.drawLine(margin, 0, margin, getMeasuredHeight(), marginPaint);
canvas.save();
canvas.translate(margin, 0);
super.onDraw(canvas);//平移后绘制文字
canvas.restore();
}
private void init(){
Resources resources = getResources();
marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
marginPaint.setColor(resources.getColor(R.color.notepad_margin));//#90ff0000
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setColor(resources.getColor(R.color.notepad_lines));//#ff0000ff
paperColor = resources.getColor(R.color.notepad_paper);//#eef8e0a0
margin = resources.getDimension(R.dimen.notepad_margin);
}
}
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="notepad_paper">#eef8e0a0</color><!-- R.color.notepad_paper -->
<color name="notepad_lines">#ff0000ff</color>
<color name="notepad_margin">#90ff0000</color>
<color name="notepad_text">#aa0000ff</color>
</resources>
dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="notepad_margin">30dp</dimen>
</resources>
2、定义ListActivity的子类及布局文件
public class MainActivity extends ListActivity {
TextView tv;
private static final String TAG = "info";
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] colors = {"red","green","blue","yellow","gray","black",
"white","purple","orange","brown",};//实例化10个TextView
ListAdapter mListAdapter = new ArrayAdapter<String>(this,
R.layout.todolist_item, colors);//参数指定item样式和data
setListAdapter(mListAdapter);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="五颜六色"
android:textColor="#ffffffff"
android:background="#88880000"/>
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"/>
</LinearLayout>
todolist_item.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 设置文本颜色 -->
<com.qinuli.textviewtest.MyTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myTextView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:scrollbars="vertical"
android:textColor="@color/notepad_text"
android:fadingEdge="vertical"/>