本文介绍一个这样婶儿的TextView,如图:
点击的时候TextView会伸缩,有种Clip的感觉,原理也很简单,就是把两个TextView重叠起来,一个现实固定的行数的文本,另一个现实全部的文本,初始化的时候,容器的高度等于固定文本的高度,完全展开时的高度等于文本显示全的高度,过程用一个动画控制就可以了。下面贴代码:
ExpandTextView.java
import android.content.Context; import android.graphics.Color; import android.text.TextUtils; import android.util.AttributeSet; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.Transformation; import android.widget.FrameLayout; import android.widget.RelativeLayout; import android.widget.TextView; /** * Created by mingwei on 1/20/16. */ public class ExpandTextView extends RelativeLayout { private TextView mText; private TextView mExpandText; private int mTextColor = Color.GRAY; private int mTextLine = 1; private int mStart; private int mEnd; private boolean isFirst = true; private boolean isExpand = false; public ExpandTextView(Context context) { this(context, null); } public ExpandTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); final ViewGroup.LayoutParams params = getLayoutParams(); if (isFirst) { isFirst = false; mText.post(new Runnable() { @Override public void run() { mStart = mText.getLineHeight() * mText.getLineCount(); params.height = mStart; setLayoutParams(params); } }); mExpandText.post(new Runnable() { @Override public void run() { mEnd = mExpandText.getLineHeight() * mExpandText.getLineCount(); } }); } } public ExpandTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); mText = new TextView(context, attrs); mText.setTextColor(mTextColor); mText.setEllipsize(TextUtils.TruncateAt.END); mText.setMaxLines(mTextLine); addView(mText, params); mExpandText = new TextView(context); mExpandText.setTextColor(Color.TRANSPARENT); addView(mExpandText, params); } public void setText(String text) { isFirst = true; mText.setText(text); mExpandText.setText(text); requestLayout(); } public void setTextColor(int color) { mTextColor = color; mText.setTextColor(color); } public void setTextSize(int size) { isFirst = true; mText.setTextSize(size); mExpandText.setTextSize(size); requestLayout(); } public void setTextMaxLine(int num) { mTextLine = num; mText.setMaxLines(num); } public void setGravity(int gravity) { mText.setGravity(gravity); mExpandText.setGravity(gravity); } public void setEllipsize(TextUtils.TruncateAt ell) { mText.setEllipsize(ell); } public void setTextLineSpacingExtra(float spac) { mText.setLineSpacing(spac, 1.0f); mExpandText.setLineSpacing(spac, 1.0f); } public TextView text() { return mText; } public TextView expandText() { return mExpandText; } public int line() { return mTextLine; } public boolean isExpand() { return isExpand; } public void expand() { if (!isExpand) { isExpand = true; mText.setTextColor(Color.TRANSPARENT); mExpandText.setTextColor(mTextColor); Animation animation = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { ViewGroup.LayoutParams params = ExpandTextView.this.getLayoutParams(); params.height = mStart + (int) ((mEnd - mStart) * interpolatedTime); setLayoutParams(params); } }; animation.setDuration(500); startAnimation(animation); } } @Override public void setLayoutParams(ViewGroup.LayoutParams params) { super.setLayoutParams(params); } public void shrink() { if (isExpand) { isExpand = false; Animation animation = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { ViewGroup.LayoutParams params = ExpandTextView.this.getLayoutParams(); params.height = mStart + (int) ((mEnd - mStart) * (1 - interpolatedTime)); setLayoutParams(params); } }; animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mText.setTextColor(mTextColor); mExpandText.setTextColor(Color.TRANSPARENT); } @Override public void onAnimationRepeat(Animation animation) { } }); animation.setDuration(500); startAnimation(animation); } } public void switchs() { if (isExpand) { shrink(); } else { expand(); } } }
使用:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 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="com.ming.expandtextview.MainActivity"> <Button android:id="@+id/expand" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:text="Expand" /> <Button android:id="@+id/strink" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toEndOf="@+id/expand" android:layout_toRightOf="@+id/expand" android:text="Strink" /> <com.ming.expandtextview.ExpandTextView android:id="@+id/expandtextview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/expand"> </com.ming.expandtextview.ExpandTextView> </RelativeLayout>
public class MainActivity extends AppCompatActivity { private Button mBtnExpand; private Button mBtnStrink; private ExpandTextView mExpandTextview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtnExpand = (Button) findViewById(R.id.expand); mBtnStrink = (Button) findViewById(R.id.strink); mExpandTextview = (ExpandTextView) findViewById(R.id.expandtextview); mExpandTextview.setTextColor(Color.BLACK); mExpandTextview.setTextSize(18); mExpandTextview.setTextMaxLine(2); mExpandTextview.setText("科技本身蕴含着一种碾压一切的力量,而这种力量会导致我们加速奔向某种设定好的结局。" + "这篇文章尝试预测未来最可能的5种结局:黄金时代,虚拟世界,冷平衡,生化人,大寂灭。"); mBtnExpand.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mExpandTextview.expand(); //或者mExpandTextview.switchs(); } }); mBtnStrink.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mExpandTextview.shrink(); } }); } }