Recently, when I was working on a project, the renderings should be folded by TextView. When the number of lines exceeds a certain number, they will be folded up and click to expand. I found some effects online and made some changes myself. Then I used it to share it with netizens.
References:Android UI realizes multi-line text collapse and expansion effect
The first type:Implemented by combining multiple layouts
Probably the steps:
- Define layout, vertical linear LinearLayout layout, TextView, and ImageView. Define the basic components in layout.
- Set the height of the TextView to the specified number of rows*row height. The reason why maxLine is not used is that maxLine will control the number of lines of the displayed text, which is inconvenient to use animation to expand all content later. Therefore, the height of the TextView here should also be wrap_content.
- Add click events to the entire layout and bind animation. When clicking, if the TextView is not expanded, it will expand to its actual height, and imageView rotates; otherwise, it will shrink to the specified number of rows*row height, and imageView rotates and retracts.
Layout file:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro xmlns:more="/apk/res-auto" xmlns:tools="/tools" android: android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=""> <TextView android: android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@android:color/black" android:textSize="18sp"> </TextView> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="More" android:textSize="18sp" android:visibility="gone"/> <ImageView android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:paddingBottom="5dip" android:paddingLeft="5dip" android:paddingRight="5dip" android:paddingTop="5dip" android:src="@drawable/ic_expand_more_red_700_24dp" android:visibility="gone" /> </RelativeLayout> <!-- The second method --> < android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" more:maxLine="2" more:text="@string/text" more:textColor="@android:color/black" more:textSize="18dip"> </> </LinearLayout>
Core code:
package ; import .; import ; import ; import ; import ; import ; import ; import ; public class MainActivity extends AppCompatActivity implements { TextView text1; ImageView mImageView1; TextView expandText; //TextMoreTextView text2; boolean isExpand;//Is the expanded status private int maxDescripLine = 3; //TextView default maximum number of display lines private int deltaValue;//Default height, that is, the height determined by maxLine in the front private int startValue;//Start height private int durationMillis = 350;//Duration of animation @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.activity_main); text1 = (TextView) findViewById(.textView1); // text2= (TextMoreTextView) findViewById(.text_textView); expandText = (TextView) findViewById(.expand_text); mImageView1 = (ImageView) findViewById(.expand_view1); (this); (getText()); //The second type can be directly set here // (getText()); // Here you can set the height of the text according to the actual situation and make a judgment (it may be that there is only one line of the text, and it will also occupy the maxDescriptLine line) (() * maxDescripLine); (new Runnable() { @Override public void run() { (() > maxDescripLine ? : ); (() > maxDescripLine ? : ); } }); } @Override public void onClick(View v) { switch (()) { case .expand_view1: zheDie(text1, mImageView1); break; } } private void zheDie(final TextView text, ImageView imageView) { isExpand = !isExpand; (); startValue = (); if (isExpand) { /** * Folding animation * Retract the starting height from the actual height */ deltaValue = () * () - startValue; RotateAnimation animation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); (durationMillis); (true); (animation); ("Collapse"); } else { /** * Expand animation *Grow from the starting height to the actual height */ deltaValue = () * maxDescripLine - startValue; RotateAnimation animation = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); (durationMillis); (true); (animation); ("More"); } Animation animation = new Animation() { protected void applyTransformation(float interpolatedTime, Transformation t) { //Show the textview height according to the percentage of ImageView rotation animation to achieve animation effect ((int) (startValue + deltaValue * interpolatedTime)); } }; (durationMillis); (animation); } }
The second typeMethod, if you use more places, you can save a lot of redundant code: you will not directly analyze the specific steps.
Core code:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MoreTextStyle"> <attr name="textSize" format="dimension"/> <attr name="textColor" format="color"/> <attr name="maxLine" format="integer" /> <attr name="text" format="string" /> </declare-styleable> </resources>
package ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; public class TextMoreTextView extends LinearLayout { protected TextView contentView; protected ImageView expandView; protected int textColor; protected float textSize; protected int maxLine; protected String text; public int defaultTextColor = ;//Default text color public int defaultTextSize = 12; //Default text size public int defaultLine = 3; //Default number of rows public TextMoreTextView(Context context, AttributeSet attrs) { super(context, attrs); initalize(); initWithAttrs(context, attrs); // bindListener(); } protected void initWithAttrs(Context context, AttributeSet attrs) { TypedArray a = (attrs, ); int textColor = (.MoreTextStyle_textColor, defaultTextColor); textSize = (.MoreTextStyle_textSize, defaultTextSize); maxLine = (.MoreTextStyle_maxLine, defaultLine); text = (.MoreTextStyle_text); bindTextView(textColor, textSize, maxLine, text); (); } protected void initalize() { setOrientation(VERTICAL); setGravity(); contentView = new TextView(getContext()); addView(contentView, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); expandView = new ImageView(getContext()); int padding = dip2px(getContext(), 5); (padding, padding, padding, padding); (.ic_expand_more_red_700_24dp); LayoutParams llp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); addView(expandView, llp); } protected void bindTextView(int color, float size, final int line, String text) { (color); (TypedValue.COMPLEX_UNIT_PX, size); (text); ViewTreeObserver observer = (); (new () { //Judge that you can get () when written in this method, otherwise 0 will be returned; @Override public void onGlobalLayout() { ViewTreeObserver obs = (); (this); if (() < line) { (() * ()); } else { (() * line); bindListener();//This method will be executed only if the number of rows is greater than the set number of rows. If the adjustment is made, there will be bugs. } //("aaa", "bindTextView111: " + ());//Return 0, why } }); post(new Runnable() { @Override public void run() { (() > line ? : ); //("aaa", "run: "+() ); } }); } protected void bindListener() { setOnClickListener(new OnClickListener() { boolean isExpand; @Override public void onClick(View v) { isExpand = !isExpand; (); final int deltaValue; final int startValue = (); int durationMillis = 350; if (isExpand) { deltaValue = () * () - startValue; RotateAnimation animation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); (durationMillis); (true); (animation); } else { deltaValue = () * maxLine - startValue; RotateAnimation animation = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); (durationMillis); (true); (animation); } Animation animation = new Animation() { protected void applyTransformation(float interpolatedTime, Transformation t) { ((int) (startValue + deltaValue * interpolatedTime)); } }; (durationMillis); (animation); } }); } public TextView getTextView() { return contentView; } public void setText(CharSequence charSequence) { (charSequence); } public static int dip2px(Context context, float dipValue) { final float scale = ().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } }
This class is written like this. Just refer to the call directly in the layout file.
Source code download:http://xiazai./201610/yuanma/Androidtextview().rar
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.