可擴充套件的TextView,ExpandableTextView與Scroller類的使用

Sahadev_發表於2014-03-17

轉載時請註明出處,尊重他人的勞動成果,謝謝。

廢話不多說,先上圖演示下成果(圖有些醜,別見怪):

最近一直在研究Scroller類的使用方法,看了很多遍別人的例子總是感覺不得要領,最後還是自己實踐一下,這個控制元件的靈感來源於stackoverflow上一個人的提問,就是這種可擴充套件的TextView,當然,人家那個很好看,那時候感覺很神奇,自從知道Scroller這個類之後就拿它來練練手吧,大夥可以隨意更改它的效果,配對了很好看的。

附上程式碼:

package com.sahadev.sildingfinishlayout;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;

public class ExpandableTextView extends RelativeLayout {
	private TextView mTextView;
	private Button mButton;
	private int mTextViewId = 567576458;// 這裡注意不要隨便填一個簡單的數字,可能會和R中的ID衝突造成無效
	private Scroller mScroller;
	private int mHeight, mWidthMeasureSpec, mButtonHeight, paddingSize = 1;
	private boolean isExpanded, WSettedFlag, HSettedFlag, onceFlag;
	private int times = 2;// 縮小的倍數,預設2倍

	public ExpandableTextView(Context context) {
		this(context, null);
	}

	public ExpandableTextView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public ExpandableTextView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		mTextView = new TextView(context);
		mTextView.setId(mTextViewId);

		mButton = new Button(context);
		mButton.setText("擴    展");
		mScroller = new Scroller(context);

		LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

		lp.addRule(RelativeLayout.BELOW, mTextViewId);
		lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
		lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);

		mButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (!isExpanded) {
					// 展開來
					mScroller.startScroll(0, mHeight / times, 0, mHeight / times);
					postInvalidate();
					isExpanded = true;
				} else {
					// 收回去
					mScroller.startScroll(0, mHeight, 0, -mHeight / times);
					postInvalidate();
					isExpanded = false;
				}
			}
		});

		addView(mTextView);
		addView(mButton, lp);

	}

	@Override
	public void computeScroll() {
		super.computeScroll();
		if (mScroller.computeScrollOffset()) {

			mTextView.setHeight(mScroller.getCurrY());
			postInvalidate();
			return;
		}
	}

	public void setTimes(int times) {
		if (times == 0) {
			throw new ArithmeticException("倍數不能為0");
		}
		this.times = times;
	}

	public void setTextViewPadding(int pixels) {
		mTextView.setPadding(pixels, pixels, pixels, 0);
		paddingSize = pixels;
	}

	public void setButtonTips(CharSequence text) {
		mButton.setText(text);
	}

	public void setText(CharSequence text) {
		mTextView.setText(text);
	}

	public void setTextColor(int color) {
		mTextView.setTextColor(color);
	}

	public void setTextSize(float size) {
		mTextView.setTextSize(size);
	}

	public void setBackgroundColor(int color) {
		mTextView.setBackgroundColor(color);
	}

	public void setWidth(int width) {
		mWidthMeasureSpec = width;
		mTextView.setWidth(width - paddingSize * 2);
		WSettedFlag = true;
	}

	public void setHeight(int height) {
		mHeight = (height - mButtonHeight) * 2;
		HSettedFlag = true;
	}

	/* onMeasure方法在重繪的時候會一直被呼叫 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		/* 此步驟只用執行一次,獲取到textView的寬度以及Button的高度以及一些初始化的值 */
		if (!WSettedFlag) {
			WSettedFlag = true;
			mWidthMeasureSpec = mTextView.getMeasuredWidth();
		}

		if (!HSettedFlag) {
			HSettedFlag = true;
			mHeight = mTextView.getMeasuredHeight();
			OtherTools.showLog("mHeight----" + mHeight);
		}

		if (!onceFlag) {
			onceFlag = true;
			mButtonHeight = mButton.getMeasuredHeight();
			OtherTools.showLog("mButtonHeight----" + mButtonHeight);
			// mTextView.setHeight(mHeight / times + mButtonHeight >
			// heightMeasureSpec ? heightMeasureSpec - mButtonHeight : mHeight /
			// times);
			mTextView.setHeight(mHeight / times);
		}
		// int tempHeight = mHeight / 2 + mButtonHeight;
		// tempHeight = tempHeight > heightMeasureSpec ? heightMeasureSpec :
		// tempHeight;
		setMeasuredDimension(mWidthMeasureSpec, mButtonHeight + mTextView.getMeasuredHeight());
	}
}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/slide"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <com.sahadev.sildingfinishlayout.ExpandableTextView
        android:id="@+id/hello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#a6c" />

</RelativeLayout>

package com.sahadev.sildingfinishlayout;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.Window;

public class MainActivity extends Activity {
	private ExpandableTextView textView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);

		textView = (ExpandableTextView) findViewById(R.id.hello);

		textView.setText("近日,多家媒體報導,山西最大的民營企業聯盛集團董事長邢利斌被警方帶據分析,邢利斌這次被警方帶走,很可能和聯盛集團債臺高築有關。不過短短几年,山西煤老闆為何就和金融機構從蜜月期走到了劍拔弩張的田地?");
		textView.setTextSize(30);
		textView.setTextColor(Color.WHITE);
		textView.setTextViewPadding(15);

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

由於還不太會往GitHub上傳東西,大家就將就著把程式碼拷貝執行吧,有什麼疑問請在下面留言。

相關文章