最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android UI實(shí)現(xiàn)多行文本折疊展開效果

 更新時(shí)間:2016年10月24日 11:52:42   作者:Qiaoidea  
這篇文章主要為大家詳細(xì)介紹了Android UI實(shí)現(xiàn)多行文本折疊展開效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

上文介紹了單行文本水平觸摸滑動(dòng)效果,通過EditText實(shí)現(xiàn)TextView單行長文本水平滑動(dòng)效果。

本文繼續(xù)介紹了多行文本折疊展開,自定義布局View實(shí)現(xiàn)多行文本折疊和展開

1.概述

經(jīng)常在APP中能看到有引用文章或大段博文的內(nèi)容,他們的展示樣式也有點(diǎn)兒意思,默認(rèn)是折疊的,當(dāng)你點(diǎn)擊文章之后它會(huì)自動(dòng)展開。再次點(diǎn)擊他又會(huì)縮回去。

網(wǎng)上有找到部分效果,感覺不是很滿意。最后自己嘗試用 自定義布局layout 寫了個(gè)demo。比較簡(jiǎn)陋,不過可以用了。有這方面需求的朋友可以稍加改造下。如有更好的創(chuàng)意,也不妨分享一下。

效果圖:

2.具體實(shí)現(xiàn)

但從實(shí)現(xiàn)效果方面來看,只用簡(jiǎn)單定義必要view即可,后變?yōu)榱朔奖銛U(kuò)展使用和挪用,又對(duì)整個(gè)布局進(jìn)行封裝,方便直接使用。

2.1 通過多個(gè)布局組合實(shí)現(xiàn)

第一想法當(dāng)然是用多個(gè)View組合來實(shí)現(xiàn)。那么久定義一個(gè)LinearLayout布局分別嵌套TextView和ImageView來做。

大概步驟:

- 定義布局,垂直的線性LinearLayout布局、TextView和ImageView。 在layout中定義基本組件。
- 設(shè)置TextView的高度為指定行數(shù)*行高。 不使用maxLine的原因是maxLine會(huì)控制顯示文本的行數(shù),不方便后邊使用動(dòng)畫展開全部內(nèi)容。因此這里TextView的高度也因該為wrap_content。
- 給整個(gè)布局添加點(diǎn)擊事件,綁定動(dòng)畫。 點(diǎn)擊時(shí),若TextView未展開則展開至其實(shí)際高度,imageView 旋轉(zhuǎn);否則回縮至 指定行數(shù)*行高 , imageView 旋轉(zhuǎn)縮回。

開始編寫代碼:

1.在xml中定義布局:

 <LinearLayout
 android:id="@+id/description_layout"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="vertical"
 android:paddingLeft="12dip"
 android:paddingRight="12dip"
 android:paddingTop="5dip" >

 <TextView
 android:id="@+id/description_view"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:textColor="@android:color/black"
 android:textSize="18dip" >
 </TextView>

 <ImageView
 android:id="@+id/expand_view"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="right"
 android:paddingBottom="5dip"
 android:paddingLeft="5dip"
 android:paddingRight="5dip"
 android:paddingTop="5dip"
 android:src="@drawable/text_ic_expand"
 android:visibility="gone" />
 </LinearLayout>

2.首先在activity中定義并初始化這些view:

public class MainActivity extends Activity {
 TextView descriptionView;
 View layoutView ,expandView; //LinearLayout布局和ImageView
 int maxDescripLine = 3; //TextView默認(rèn)最大展示行數(shù)

 //在OnCreate中初始化
 {
 layoutView = findViewById(R.id.description_layout);
 descriptionView = (TextView)findViewById(R.id.description_view);
 expandView = findViewById(R.id.expand_view);
 }
}

3.然后設(shè)置textview顯示文本,再根據(jù)默認(rèn)展示行數(shù)設(shè)置其高度,并根據(jù)其是否已完全顯示(當(dāng)前展示行數(shù)是否大于等于實(shí)際行數(shù))來判斷需不需要點(diǎn)擊更多按鈕。

 //設(shè)置文本
 descriptionView.setText(getText(R.string.content));

 //descriptionView設(shè)置默認(rèn)顯示高度
 descriptionView.setHeight(descriptionView.getLineHeight() * maxDescripLine);
 //根據(jù)高度來判斷是否需要再點(diǎn)擊展開
 descriptionView.post(new Runnable() {

 @Override
 public void run() {
 expandView.setVisibility(descriptionView.getLineCount() > maxDescripLine ? View.VISIBLE : View.GONE);
 }
 }); 

因?yàn)閠extView設(shè)置的是wrap_content,所以會(huì)顯示實(shí)際高度和行數(shù),這里根據(jù)maxDescripLine來設(shè)置其高度。
看了最后一行代碼可能有人會(huì)問?ImageView (點(diǎn)擊展開更多)是否應(yīng)該顯示 的判斷邏輯為什么要放在post方法里邊呢? 這是由于在OnCreate方法中定義設(shè)置的textView不會(huì)馬上渲染并顯示,所以textview的getLineCount()獲取到的值一般都為零,因此使用post會(huì)在其繪制完成后來對(duì)ImageView進(jìn)行顯示控制。
ps: 感覺我描述不清的朋友可以看下stackoverflow 上的講解 how to use getlinecount() in textview android.

4.給layoutView設(shè)置點(diǎn)擊事件。

給ImageView定義一個(gè)RotateAnimation的旋轉(zhuǎn)動(dòng)畫,在旋轉(zhuǎn)過程中根據(jù)旋轉(zhuǎn)百分比進(jìn)度控制textView高度,進(jìn)而達(dá)到我們想要的效果。

 layoutView.setOnClickListener(new View.OnClickListener() {
 boolean isExpand;//是否已展開的狀態(tài)

 @Override
 public void onClick(View v) {
 isExpand = !isExpand;
 descriptionView.clearAnimation();//清楚動(dòng)畫效果
 final int deltaValue;//默認(rèn)高度,即前邊由maxLine確定的高度
 final int startValue = descriptionView.getHeight();//起始高度
 int durationMillis = 350;//動(dòng)畫持續(xù)時(shí)間
 if (isExpand) {
 /**
 * 折疊動(dòng)畫
 * 從實(shí)際高度縮回起始高度
 */
 deltaValue = descriptionView.getLineHeight() * descriptionView.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 {
 /**
 * 展開動(dòng)畫
 * 從起始高度增長至實(shí)際高度
 */
 deltaValue = descriptionView.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);
 expandView.startAnimation(animation);
 }
 Animation animation = new Animation() {
 protected void applyTransformation(float interpolatedTime, Transformation t) { //根據(jù)ImageView旋轉(zhuǎn)動(dòng)畫的百分比來顯示textview高度,達(dá)到動(dòng)畫效果
 descriptionView.setHeight((int) (startValue + deltaValue * interpolatedTime));
 }
 };
 animation.setDuration(durationMillis);
 descriptionView.startAnimation(animation);
 }
 });

至此,通過布局已經(jīng)實(shí)現(xiàn)了我們想要的效果。具體代碼參見代碼示例 的第一部分。
當(dāng)然,我們可以這樣使用,但是每次都這么重寫未免顯得有些麻煩。因此有必要把他寫成一個(gè)單獨(dú)控件,方便我們以后的開袋即食。廢話不多說,上菜。

2.2 通過自定義View組合封裝

這個(gè)view的布局結(jié)構(gòu)并不打算使用xml來定義layout,直接定義一個(gè)繼承LinearLayout的MoreTextView類.這個(gè)類里邊添加TextView和ImageView。

1.使用styleable自定義View屬性

為了后邊能夠方便的在xml布局中使用MoreTextView這個(gè)自定義View,類似通過

android:text = “XXX”
android:textSize = “XXX”

這樣快捷的綁定文本內(nèi)容和設(shè)置字體大小等屬性,我們可以通過 declare-styleable在values文件下的xml中自定義我們想要的屬性,并在View中獲取和使用。詳細(xì)使用declare-styleable的內(nèi)容會(huì)在后邊補(bǔ)充,這里簡(jiǎn)要說下。
比如,MoreTextView應(yīng)該有的基本屬性,像 文本字體大小(textSize)、顏色(textColor)和文本內(nèi)容(text),還有默認(rèn)顯示行數(shù)(maxLine)等幾種屬性。我們要想像TextView一樣直接在xml中設(shè)置綁定,可以這樣做。
首先在values目錄下新建個(gè)attrs.xml(名字隨意),并定義MoreTextView這些屬性。

<?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>

2.自定義MoreTextView并獲取這些屬性的值

  上邊定義了這些屬性,就等于允許我們?cè)趚ml中使用

more:text = “XXX”
more:textSize = “XXX”
more : textColor = “XXX”
more : maxLine = “XXX”
(注: more這個(gè)關(guān)鍵字可以隨意)

這樣直接設(shè)置屬性值。那么具體怎么取值,我們稍后來講。

(1)定義MoreTextView的屬性:

public class MoreTextView extends LinearLayout{
 protected TextView contentView; //文本正文
 protected ImageView expandView; //展開按鈕

 //對(duì)應(yīng)styleable中的屬性
 protected int textColor; 
 protected float textSize;
 protected int maxLine;
 protected String text;

 //默認(rèn)屬性值
 public int defaultTextColor = Color.BLACK;
 public int defaultTextSize = 12;
 public int defaultLine = 3;

 //....實(shí)現(xiàn)部分略
}

(2)MoreTextView的構(gòu)造方法:

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

這三個(gè)方法簡(jiǎn)單說明下:

initalize()初始化并添加View。初始化TextView和ImageView,并添加到MoretextView中去。
initWithAttrs(context, attrs)取值并設(shè)置。利用attrs從xml布局中取我們配置好的text/textSize/textColor/maxLine等屬性的屬性值,并設(shè)置到View上去。
bindListener()綁定點(diǎn)擊事件并設(shè)置動(dòng)畫。 給當(dāng)前MoreTextView設(shè)置點(diǎn)擊事件,實(shí)現(xiàn)點(diǎn)擊折疊和展開。

各個(gè)方法的具體實(shí)現(xiàn):

//初始化并添加View
protected void initalize() {
 setOrientation(VERTICAL); //設(shè)置垂直布局
 setGravity(Gravity.RIGHT); //右對(duì)齊
 //初始化textView并添加
 contentView = new TextView(getContext());
 addView(contentView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
 //初始化ImageView并添加
 expandView = new ImageView(getContext());
 int padding = dip2px(getContext(), 5);
 expandView.setPadding(padding, padding, padding, padding);
 expandView.setImageResource(R.drawable.text_ic_expand);
 LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
 addView(expandView, llp);

取值并設(shè)置這部分有必要將一下。我們利用TypedArray從定義的styleable中取出屬性值,賦給我們定義好的類的屬性變量。記得取完之后調(diào)用recycle()回收釋放。

 protected void initWithAttrs(Context context, AttributeSet attrs) {
 TypedArray a = context.obtainStyledAttributes(attrs, 
 R.styleable.MoreTextStyle); 
 int textColor = a.getColor(R.styleable.MoreTextStyle_textColor, 
 defaultTextColor); //取顏色值,默認(rèn)defaultTextColor
 textSize = a.getDimensionPixelSize(R.styleable.MoreTextStyle_textSize, defaultTextSize);//取顏?zhàn)煮w大小,默認(rèn)defaultTextSize
 maxLine = a.getInt(R.styleable.MoreTextStyle_maxLine, defaultLine);//取顏顯示行數(shù),默認(rèn)defaultLine
 text = a.getString(R.styleable.MoreTextStyle_text);//取文本內(nèi)容

 //綁定到textView bindTextView(textColor,textSize,maxLine,text);

 a.recycle();//回收釋放
 }

 //綁定到textView 
 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);
 contentView.setHeight(contentView.getLineHeight() * line);
 post(new Runnable() {//前面已講,不再贅述

 @Override
 public void run() {
 expandView.setVisibility(contentView.getLineCount() > line ? View.VISIBLE : View.GONE);

 }
 });
 }

最后設(shè)置點(diǎn)擊事件。

 //點(diǎn)擊展開與折疊,不再贅述
 protected void bindListener(){
 setOnClickListener(new View.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);
 }
 });
 }

另外,定義幾個(gè)方法方便外部調(diào)用(獲取文本TextView,直接設(shè)置文本內(nèi)容),同時(shí)還定義了一個(gè)dip轉(zhuǎn)像素的靜態(tài)方法。

 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); 
 } 

其實(shí)到這里,我們的自定義多文本折疊展開MoreTextView已經(jīng)完成了。如何使用呢?

在layout/xx.xml中使用

要想方便的使用我們剛剛的自定義屬性來定義值,記得在xml namespace中定義應(yīng)用:

自動(dòng)引用命名空間res-auto
xmlns:more=”http://schemas.android.com/apk/res-auto”
或者 直接定義包名
xmlns:more=”http://schemas.android.com/apk/res/com.qiao.moretext”
命名空間后邊跟的 more即下邊你要使用自定義屬性的開頭部分。
比如我們的activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:more="http://schemas.android.com/apk/res/com.qiao.moretext"
 android:id="@+id/root"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@android:color/white"
 android:orientation="vertical" >

 <com.qiao.moretext.MoreTextView
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_margin="5dip" 
 more:textColor="@android:color/black"
 more:textSize="18dip"
 more:maxLine="3"
 more:text="@string/content"/>

</LinearLayout>

在java中直接定義使用
由于上邊定義MoreTextView只定義了一種構(gòu)造方法 MoreTextView(Context context, AttributeSet attrs) ,所以使用時(shí),也只能:

 MoreTextView content = new MoreTextView(MainActivity.this, null);
 content.setText(getText(R.string.content));
 //然后addview到你要添加的地方

  當(dāng)然,聰明如你,可肯定知道怎么定義另外的構(gòu)造方法來簡(jiǎn)單實(shí)用啦。 
  –> 
  MoreTextView(Context context){ 
    //使用默認(rèn)值直接初始化 
    bindTextView(); 
  }

3.綜述

綜上呢,我們已經(jīng)完成了所要實(shí)現(xiàn)的功能,作為UI呢,他可能會(huì)有些簡(jiǎn)陋,但作為一個(gè)demo起到示范作用已經(jīng)夠了。后邊我們可能會(huì)考慮把它作為微博的一個(gè)listitem做成列表一樣,并加入點(diǎn)贊等功能。有興趣不妨做一下咯。

源碼示例下載地址:http://xiazai.jb51.net/201610/yuanma/Androidtouchmove(jb51.net).rar

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android編程應(yīng)用風(fēng)格和主題詳解

    Android編程應(yīng)用風(fēng)格和主題詳解

    這篇文章主要介紹了Android編程應(yīng)用風(fēng)格和主題,較為詳細(xì)的分析了Android應(yīng)用風(fēng)格和主題的概念、功能、使用方法與注意事項(xiàng),需要的朋友可以參考下
    2016-10-10
  • Android獲取SDcard目錄及創(chuàng)建文件夾的方法

    Android獲取SDcard目錄及創(chuàng)建文件夾的方法

    今天小編就為大家分享一篇Android獲取SDcard目錄及創(chuàng)建文件夾的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Android手機(jī)App安全漏洞整理(小結(jié))

    Android手機(jī)App安全漏洞整理(小結(jié))

    這篇文章主要介紹了Android手機(jī)App安全漏洞整理(小結(jié)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • Android 8.0如何完美適配全局dialog懸浮窗彈出

    Android 8.0如何完美適配全局dialog懸浮窗彈出

    這篇文章主要給大家介紹了關(guān)于Android 8.0如何完美適配全局dialog懸浮窗彈出的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起看看吧
    2018-07-07
  • android中Activity橫豎屏切換的那些事

    android中Activity橫豎屏切換的那些事

    本篇文章主要介紹了android中Activity橫豎屏切換的那些事,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • Android如何通過Retrofit提交Json格式數(shù)據(jù)

    Android如何通過Retrofit提交Json格式數(shù)據(jù)

    本篇文章主要介紹了Android如何通過Retrofit提交Json格式數(shù)據(jù),具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08
  • Android Studio中導(dǎo)入module的方法(簡(jiǎn)單版)

    Android Studio中導(dǎo)入module的方法(簡(jiǎn)單版)

    這篇文章主要介紹了AndroidStudio中導(dǎo)入module的方法,本文是一篇簡(jiǎn)易版的教程,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Flutter使用AnimatedOpacity實(shí)現(xiàn)圖片漸現(xiàn)動(dòng)畫

    Flutter使用AnimatedOpacity實(shí)現(xiàn)圖片漸現(xiàn)動(dòng)畫

    其實(shí)在Flutter中提供了一些封裝好的動(dòng)畫組件,以便我們快速應(yīng)用。本文將利用其中的AnimatedOpacity組件實(shí)現(xiàn)圖片漸現(xiàn)動(dòng)畫效果,需要的可以參考一下
    2022-03-03
  • Android自定義View仿QQ等級(jí)天數(shù)進(jìn)度

    Android自定義View仿QQ等級(jí)天數(shù)進(jìn)度

    這篇文章主要為大家詳細(xì)介紹了Android自定義View仿QQ等級(jí)天數(shù)進(jìn)度效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Android繪制簡(jiǎn)單條形圖

    Android繪制簡(jiǎn)單條形圖

    這篇文章主要為大家詳細(xì)介紹了Android繪制簡(jiǎn)單條形圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08

最新評(píng)論

许昌县| 泗阳县| 平邑县| 东乡| 漠河县| 四子王旗| 获嘉县| 台州市| 武夷山市| 辽宁省| 东光县| 西乡县| 湟中县| 屏山县| 高尔夫| 陆良县| 东台市| 鸡东县| 巫溪县| 油尖旺区| 剑阁县| 康保县| 焦作市| 驻马店市| 祁连县| 翁牛特旗| 朝阳市| 定南县| 义乌市| 清水河县| 大同市| 临洮县| 镇远县| 华蓥市| 无为县| 神农架林区| 渑池县| 寻乌县| 晋州市| 潼南县| 丰县|