1. 程式人生 > >[Android]自定義一個可以展開顯示更多的文字佈局

[Android]自定義一個可以展開顯示更多的文字佈局

在查閱其他博主的博文中,發現了一個比較不錯的文字伸展的效果,在此借鑑學習。可以先看看到底是什麼樣的效果


看起來很眼熟吧,很多應用中都有這樣的使用場景,其實就是控制textview的maxlines屬性,來做的。在這裡就簡單的說下定義的過程

1.stretchy_text_layout.xml --這是建立一個佈局,用來裝裱以上展示的控制元件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/content_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4.0dip"
        android:ellipsize="end"
        android:gravity="center_vertical"
        android:textColor="#ff000000"
        android:textSize="14.0dip" />

    <LinearLayout
        android:id="@+id/bottom_text_layout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/bottom_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="2dp"
            android:layout_marginTop="2dp"
            android:gravity="center"
            android:padding="2dp"
            android:singleLine="true"
            android:textColor="#ff576b95"
            android:textSize="15.0dip"
            android:visibility="visible" />
    </LinearLayout>
</LinearLayout>
2.在string.xml中定義兩個後面需要顯示的內容
<string name="retract">收起</string>
	<string name="spread">展開</string>
3.主要的程式碼StretchyTextView.java --繼承線性佈局linearlayout,對其中的控制元件做狀態的預判,並更改content TextView的最大顯示行數。做到我們想要的效果。
/**
 * 可伸展的文字顯示佈局
 * @author jan
 */
public class StretchyTextView extends LinearLayout implements OnClickListener {
	//預設顯示的最大行數
	private static final int DEFAULT_MAX_LINE_COUNT = 2;
	//當前展開標誌顯示的狀態
	private static final int SPREADTEXT_STATE_NONE = 0;
	private static final int SPREADTEXT_STATE_RETRACT = 1;
	private static final int SPREADTEXT_STATE_SPREAD = 2;
	
	private TextView contentText;
	private TextView operateText;
	private LinearLayout bottomTextLayout;

	private String shrinkup;
	private String spread;
	private int mState;
	private boolean flag = false;
	private int maxLineCount = DEFAULT_MAX_LINE_COUNT;
	private InnerRunnable runable;

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

	public StretchyTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
		shrinkup = context.getString(R.string.retract);
		spread = context.getString(R.string.spread);
		View view = inflate(context, R.layout.stretchy_text_layout, this);
		view.setPadding(0, -1, 0, 0);
		contentText = (TextView) view.findViewById(R.id.content_textview);
		operateText = (TextView) view.findViewById(R.id.bottom_textview);
		bottomTextLayout = (LinearLayout) view.findViewById(R.id.bottom_text_layout);
		setBottomTextGravity(Gravity.LEFT);
		operateText.setOnClickListener(this);
		runable = new InnerRunnable();
	}

	@Override
	public void onClick(View v) {
		flag = false;
		requestLayout();
	}

	public final void setContent(CharSequence charSequence) {
		contentText.setText(charSequence, BufferType.NORMAL);
		mState = SPREADTEXT_STATE_SPREAD;
		Log.d("setContent", "count lines="+contentText.getLineCount()+",flag="+flag);
		flag = false;
		requestLayout();
	}

	@SuppressLint("DrawAllocation")
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		if (!flag) {
			flag = !flag;
			if (contentText.getLineCount() <= DEFAULT_MAX_LINE_COUNT) {
				mState = SPREADTEXT_STATE_NONE;
				operateText.setVisibility(View.GONE);
				contentText.setMaxLines(DEFAULT_MAX_LINE_COUNT + 1);
			}else {
				post(runable);
			}
		}
	}

	class InnerRunnable implements Runnable {
		@Override
		public void run() {
			if (mState == SPREADTEXT_STATE_SPREAD) {
				contentText.setMaxLines(maxLineCount);
				operateText.setVisibility(View.VISIBLE);
				operateText.setText(spread);
				mState = SPREADTEXT_STATE_RETRACT;
			} else if (mState == SPREADTEXT_STATE_RETRACT) {
				contentText.setMaxLines(Integer.MAX_VALUE);
				operateText.setVisibility(View.VISIBLE);
				operateText.setText(shrinkup);
				mState = SPREADTEXT_STATE_SPREAD;
			}
		}
	}

	public void setMaxLineCount(int maxLineCount) {
		this.maxLineCount = maxLineCount;
	}
	
	public void setContentTextColor(int color){
		this.contentText.setTextColor(color);
	}
	
	public void setContentTextSize(float size){
		this.contentText.setTextSize(size);
	}
	/**
	 * 內容字型加粗
	 */
	public void setContentTextBold(){
		TextPaint textPaint = contentText.getPaint();
		textPaint.setFakeBoldText(true);
	}
	/**
	 * 設定展開標識的顯示位置
	 * @param gravity
	 */
	public void setBottomTextGravity(int gravity){
		bottomTextLayout.setGravity(gravity);
	}
}

4.使用

在其它需要的佈局中引入 自定義的layout

<org.jan.okhttp.demo.StretchyTextView
            android:id="@+id/spread_textview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

然後在程式碼中find出來,設定內容。
spreadTextView = (StretchyTextView) findViewById(R.id.spread_textview);
		spreadTextView.setMaxLineCount(3);
		spreadTextView.setContent("近些年來,越來越多的行業開始和網際網路結合,誕生了越來越多的網際網路創業公司。網際網路創業公司需要面對許多的不確定因素。如果你和你的小夥伴們夠幸運,你們的公司可能會在幾個星期之內讓使用者數、商品數、訂單量增長几十倍上百倍。一次促銷可能會帶來平時幾十倍的訪問流量,一次秒殺活動可能會吸引平時數百倍的訪問使用者。這對公司自然是極大的好事,說明產品得到認可,公司未來前景美妙。");

是不是很簡單啊!

相關參考: