Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android TextView多文本折疊展開效果

Android TextView多文本折疊展開效果

編輯:關於Android編程

最近做項目,效果圖要用到TextView的折疊,超過一定行數的時候,就會折疊起來,點擊可以展開。網上找了一些效果,自己也稍作了修改。便拿來與網友分享分享。
參考文獻:http://www.jb51.net/article/95544.htm

第一種:通過多個布局組合實現
大概步驟:
- 定義布局,垂直的線性LinearLayout布局、TextView和ImageView。 在layout中定義基本組件。
- 設置TextView的高度為指定行數*行高。 不使用maxLine的原因是maxLine會控制顯示文本的行數,不方便後邊使用動畫展開全部內容。因此這裡TextView的高度也因該為wrap_content。
- 給整個布局添加點擊事件,綁定動畫。 點擊時,若TextView未展開則展開至其實際高度,imageView 旋轉;否則回縮至 指定行數*行高 , imageView 旋轉縮回。
布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:more="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/activity_main"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context="com.example.my.textviewdemotest.MainActivity">

 <TextView
 android:id="@+id/textView1"
 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:id="@+id/expand_text"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="更多"
 android:textSize="18sp"
 android:visibility="gone"/>

 <ImageView
 android:id="@+id/expand_view1"
 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>
 <!-- 第二種方法 -->
 <com.example.my.textviewdemotest.TextMoreTextView
 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">
 </com.example.my.textviewdemotest.TextMoreTextView>
</LinearLayout>

核心代碼:

package com.example.my.textviewdemotest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

 TextView text1;
 ImageView mImageView1;
 TextView expandText;
 //TextMoreTextView text2;

 boolean isExpand;//是否已展開的狀態
 private int maxDescripLine = 3; //TextView默認最大展示行數
 private int deltaValue;//默認高度,即前邊由maxLine確定的高度
 private int startValue;//起始高度
 private int durationMillis = 350;//動畫持續時間

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 text1 = (TextView) findViewById(R.id.textView1);
 // text2= (TextMoreTextView) findViewById(R.id.text_textView);
 expandText = (TextView) findViewById(R.id.expand_text);

 mImageView1 = (ImageView) findViewById(R.id.expand_view1);
 mImageView1.setOnClickListener(this);

 text1.setText(getText(R.string.text));
 //第二種可以在這裡直接設置文字
 // text2.setText(getText(R.string.text));
 //這裡大家可以根據實際情況來設置文字的高度,做個判斷(可能會文字只有一行,也會占據maxDescripLine行)
 text1.setHeight(text1.getLineHeight() * maxDescripLine);
 text1.post(new Runnable() {
 @Override
 public void run() {
 mImageView1.setVisibility(text1.getLineCount() > maxDescripLine ? View.VISIBLE : View.GONE);
 expandText.setVisibility(text1.getLineCount() > maxDescripLine ? View.VISIBLE : View.GONE);
 }
 });
 }

 @Override
 public void onClick(View v) {
 switch (v.getId()) {
 case R.id.expand_view1:
 zheDie(text1, mImageView1);
 break;
 }

 }

 private void zheDie(final TextView text, ImageView imageView) {
 isExpand = !isExpand;
 text.clearAnimation();
 startValue = text.getHeight();
 if (isExpand) {
 /**
 * 折疊動畫
 * 從實際高度縮回起始高度
 */
 deltaValue = text.getLineHeight() * text.getLineCount() - startValue;
 RotateAnimation animation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
 animation.setDuration(durationMillis);
 animation.setFillAfter(true);
 imageView.startAnimation(animation);
 expandText.setText("收起");
 } else {
 /**
 * 展開動畫
 * 從起始高度增長至實際高度
 */
 deltaValue = text.getLineHeight() * maxDescripLine - startValue;
 RotateAnimation animation = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
 animation.setDuration(durationMillis);
 animation.setFillAfter(true);
 imageView.startAnimation(animation);
 expandText.setText("更多");
 }
 Animation animation = new Animation() {
 protected void applyTransformation(float interpolatedTime, Transformation t) { //根據ImageView旋轉動畫的百分比來顯示textview高度,達到動畫效果
 text.setHeight((int) (startValue + deltaValue * interpolatedTime));
 }
 };
 animation.setDuration(durationMillis);
 text.startAnimation(animation);
 }
}

第二種方法,如果用的地方多可以省去很多冗余代碼:具體步驟就不直接分析。
核心代碼:

<?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 com.example.my.textviewdemotest;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

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 = Color.BLACK;//默認文字顏色
 public int defaultTextSize = 12; //默認文字大小
 public int defaultLine = 3; //默認行數

 public TextMoreTextView(Context context, AttributeSet attrs) {
 super(context, attrs);
 initalize();
 initWithAttrs(context, attrs);
 // bindListener();
 }

 protected void initWithAttrs(Context context, AttributeSet attrs) {
 TypedArray a = context.obtainStyledAttributes(attrs,
 R.styleable.MoreTextStyle);
 int textColor = a.getColor(R.styleable.MoreTextStyle_textColor,
 defaultTextColor);
 textSize = a.getDimensionPixelSize(R.styleable.MoreTextStyle_textSize, defaultTextSize);
 maxLine = a.getInt(R.styleable.MoreTextStyle_maxLine, defaultLine);
 text = a.getString(R.styleable.MoreTextStyle_text);
 bindTextView(textColor, textSize, maxLine, text);
 a.recycle();
 }

 protected void initalize() {
 setOrientation(VERTICAL);
 setGravity(Gravity.RIGHT);
 contentView = new TextView(getContext());
 addView(contentView, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
 expandView = new ImageView(getContext());
 int padding = dip2px(getContext(), 5);
 expandView.setPadding(padding, padding, padding, padding);
 expandView.setImageResource(R.drawable.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) {
 contentView.setTextColor(color);
 contentView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
 contentView.setText(text);
 ViewTreeObserver observer = contentView.getViewTreeObserver();
 observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
 //判斷寫在這個方法裡面能拿到contentView.getLineCount(),否則返回時0;
 @Override
 public void onGlobalLayout() {
 ViewTreeObserver obs = contentView.getViewTreeObserver();
 obs.removeGlobalOnLayoutListener(this);
 if (contentView.getLineCount() < line) {
  contentView.setHeight(contentView.getLineHeight() * contentView.getLineCount());
 } else {
  contentView.setHeight(contentView.getLineHeight() * line);
  bindListener();//只有在行數大於設定行數才會執行這個方法,做了調整否則會有bug。
 }
 //Log.e("aaa", "bindTextView111: " + contentView.getLineCount());//返回0,為什麼
 }
 });

 post(new Runnable() {
 @Override
 public void run() {
 expandView.setVisibility(contentView.getLineCount() > line ? View.VISIBLE : View.GONE);
 //Log.e("aaa", "run: "+contentView.getLineCount() );
 }
 });
 }

 protected void bindListener() {
 setOnClickListener(new OnClickListener() {
 boolean isExpand;

 @Override
 public void onClick(View v) {
 isExpand = !isExpand;
 contentView.clearAnimation();
 final int deltaValue;
 final int startValue = contentView.getHeight();
 int durationMillis = 350;
 if (isExpand) {
  deltaValue = contentView.getLineHeight() * contentView.getLineCount() - startValue;
  RotateAnimation animation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
  animation.setDuration(durationMillis);
  animation.setFillAfter(true);
  expandView.startAnimation(animation);
 } else {
  deltaValue = contentView.getLineHeight() * maxLine - startValue;
  RotateAnimation animation = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
  animation.setDuration(durationMillis);
  animation.setFillAfter(true);
  expandView.startAnimation(animation);
 }
 Animation animation = new Animation() {
  protected void applyTransformation(float interpolatedTime, Transformation t) {
  contentView.setHeight((int) (startValue + deltaValue * interpolatedTime));
  }

 };
 animation.setDuration(durationMillis);
 contentView.startAnimation(animation);
 }
 });
 }

 public TextView getTextView() {
 return contentView;
 }

 public void setText(CharSequence charSequence) {
 contentView.setText(charSequence);
 }

 public static int dip2px(Context context, float dipValue) {
 final float scale = context.getResources().getDisplayMetrics().density;
 return (int) (dipValue * scale + 0.5f);
 }
}

這個類這樣就寫好了。調用直接在布局文件中引用就行了。

源碼下載:http://xiazai.jb51.net/201610/yuanma/Androidtextview(jb51.net).rar

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved