[Android]自定义一个可以展开显示更多的文本布局

在查阅其他博主的博文中,发现了一个比较不错的文本伸展的效果,在此借鉴学习。可以先看看到底是什么样的效果

[Android]自定义一个可以展开显示更多的文本布局_第1张图片

看起来很眼熟吧,很多应用中都有这样的使用场景,其实就是控制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("近些年来,越来越多的行业开始和互联网结合,诞生了越来越多的互联网创业公司。互联网创业公司需要面对许多的不确定因素。如果你和你的小伙伴们够幸运,你们的公司可能会在几个星期之内让用户数、商品数、订单量增长几十倍上百倍。一次促销可能会带来平时几十倍的访问流量,一次秒杀活动可能会吸引平时数百倍的访问用户。这对公司自然是极大的好事,说明产品得到认可,公司未来前景美妙。");

是不是很简单啊!


相关参考:

1.Android编程之仿微信显示更多文字的View


你可能感兴趣的:([Android]自定义一个可以展开显示更多的文本布局)