TextView及其子类

本文总结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"/>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值