可伸缩的TextView

来源:互联网 发布:史崔克装甲车数据 编辑:程序博客网 时间:2024/04/29 19:27

1.效果图

这里写图片描述

2.实现的功能

1.当显示的内容不多于2行时,和普通的TextView一样
2.当显示的内容大于2行时,仅仅显示两行,并且没有显示完的内容使用省略号代替,并显示向下箭头表示还有内容没有显示全当用户点击TextView时,内容全部展开,当用户再次点击时,TextView又变为压缩模式

3.自定义控件ExpandTextView

/** * 可伸缩的TextView * <p> * xml文件中使用该自定义View Demo: * <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:expand="http://schemas.android.com/apk/res/com.gavin.expandable.textview"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.gavin.expandable.textview.MainActivity" >    <com.gavin.expandable.textview.ExpandTextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        expand:text="@string/content_one"        expand:textcolor="#FF0000"        expand:textsize="15sp"        expand:icon="@drawable/text_expand"        expand:lines="2"        /> * </LinearLayout> * </p> * <p> *  text:设置ExpandTextView的文本内容 *  textcolor:设置文本的颜色 *  textsize:设置文本字体大小 *  icon:设置展开和压缩的图标 *  lines:设置压缩时(非展开),显示多少行 * </p> */public class ExpandTextView extends LinearLayout implements OnClickListener{  public static final String TAG="ExpandTextView";  public static final int DEFAULT_TEXT_COLOR=0XFF000000;  public static final int DEFAULT_LINE_NUM=3;  public static final int DEFAULT_TEXT_SIZE=12;  public static final int DEFAULT_MARGIN_TOP=10;  private TextView mTextView;  private ImageView mImageView;  /**TextView字体的颜色*/  private int textColor;  /**TextView字体的大小*/  private float textSize;  /**TextView默认显示行数*/  private int maxLine;  /**TextView的文本内容*/  private String text;  /**ImageView使用的图片*/  private Drawable mIcon;  /**TextView所有的内容暂用的行数*/  private int contentLine=0;  /**是否展开*/  private boolean isExpand=false;  public ExpandTextView(Context context) {    super(context);    init(null,0);  }  public ExpandTextView(Context context, AttributeSet attrs) {    super(context, attrs);    init(attrs,0);  }  public ExpandTextView(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    init(attrs,defStyleAttr);  }//  @TargetApi(Build.VERSION_CODES.LOLLIPOP)//  public ExpandTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {//    super(context, attrs, defStyleAttr, defStyleRes);//    init(attrs,defStyleAttr);//  }  private void init(AttributeSet attrs,int defStyleAttr){    setOrientation(VERTICAL);    setGravity(Gravity.CENTER_HORIZONTAL);    TypedArray array=this.getContext().obtainStyledAttributes(attrs, R.styleable.ExpandTextView,defStyleAttr,0);    textColor=array.getColor(R.styleable.ExpandTextView_textcolor,DEFAULT_TEXT_COLOR);    textSize=array.getDimensionPixelOffset(R.styleable.ExpandTextView_textsize,dp2px(DEFAULT_TEXT_SIZE));    maxLine=array.getInt(R.styleable.ExpandTextView_lines,DEFAULT_LINE_NUM);    mIcon=array.getDrawable(R.styleable.ExpandTextView_icon);    text=array.getString(R.styleable.ExpandTextView_text);    if(mIcon==null){      mIcon=this.getContext().getResources().getDrawable(R.drawable.text_expand);    }    array.recycle();  }  public void setText(String text) {      this.text=text;      initViewAttribute();}  private void initViewAttribute(){    mTextView=new TextView(this.getContext());    //设置属性    mTextView.setText(text);    mTextView.setTextColor(textColor);    mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);    int textHeight=mTextView.getLineHeight()*maxLine;    LayoutParams mParams_txt=new LayoutParams(LayoutParams.MATCH_PARENT,textHeight);    addView(mTextView,mParams_txt);    mImageView=new ImageView(this.getContext());    mImageView.setImageDrawable(mIcon);    LayoutParams mParams_img=new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);    mParams_img.topMargin=dp2px(DEFAULT_MARGIN_TOP);    addView(mImageView,mParams_img);    mImageView.setOnClickListener(this);    this.setOnClickListener(this);    this.post(new Runnable() {      @Override      public void run() {        contentLine=mTextView.getLineCount();        if(contentLine<=maxLine){          mImageView.setVisibility(View.GONE);          LayoutParams mParam=(LayoutParams) mTextView.getLayoutParams();          mParam.height=LayoutParams.WRAP_CONTENT;          mTextView.setLayoutParams(mParam);          ExpandTextView.this.setOnClickListener(null);        }else{          //默认是非展开模式,那么设置最大行为maxLine          mTextView.setMaxLines(maxLine);          mTextView.setEllipsize(TruncateAt.END);          mImageView.setVisibility(View.VISIBLE);        }      }    });  }  /**   * dp单位和px单位的转化   * @param dp   * @return   */  private int dp2px(int dp){    return (int)(this.getResources().getDisplayMetrics().density*dp+0.5);  }  @Override  public void onClick(View v) {    if(v==mImageView|| v==this){      flexibleHeight();    }  }  /**   * 对TextView进行伸缩处理   */  private void flexibleHeight() {    isExpand=!isExpand;    int textHeight=0;    float startDegree=0.0f;    float endDegree=180.0f;    if(isExpand){      //如果是展开模式,那么取消最大行为maxLine的限制      textHeight=contentLine*mTextView.getLineHeight();      mTextView.setMaxLines(contentLine);    }else{      textHeight=mTextView.getLineHeight()*maxLine;      endDegree=0.0f;      startDegree=180.0f;    }    final LayoutParams mParam=(LayoutParams) mTextView.getLayoutParams();    //TextView的平移动画    ValueAnimator animator_textView= ValueAnimator.ofInt(mTextView.getHeight(),textHeight);    animator_textView.addUpdateListener(new AnimatorUpdateListener() {      @Override      public void onAnimationUpdate(ValueAnimator animation) {        mParam.height=(Integer)animation.getAnimatedValue();        mTextView.setLayoutParams(mParam);      }    });    //imageView的旋转动画    ObjectAnimator animator_img=ObjectAnimator.ofFloat(mImageView, "rotation", startDegree, endDegree);    AnimatorSet mAnimatorSets=new AnimatorSet();    mAnimatorSets.setDuration(500);    mAnimatorSets.play(animator_img).with(animator_textView);    mAnimatorSets.start();    mAnimatorSets.addListener(new AnimatorListenerAdapter(){      @Override      public void onAnimationEnd(Animator animation) {        super.onAnimationEnd(animation);        //动画结束之后,如果是非展开模式,则设置最大行数为maxLine        if(!isExpand){          mTextView.setMaxLines(maxLine);        }      }    });  }}

4.自定义控件的属性设置

values文件夹下新建attrs.xml文件

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="ExpandTextView">        <attr name="textcolor" format="color"></attr>        <attr name="textsize" format="dimension"></attr>        <attr name="icon" format="reference"></attr>        <attr name="lines" format="integer"></attr>        <attr name="text" format="string"></attr>    </declare-styleable></resources>

5.布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:expand="http://schemas.android.com/apk/res/com.gavin.expandable.textview"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.gavin.expandable.textview.MainActivity" >    <com.gavin.expandable.textview.ExpandTextView        android:id="@+id/expand"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        expand:text="@string/content_one"        expand:textcolor="#FF0000"        expand:textsize="15sp"        expand:icon="@drawable/text_expand"        expand:lines="2"        />    <TextView         android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="线程安全"        /></LinearLayout>

6.主程序代码

public class MainActivity extends Activity {private ExpandTextView tv;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    tv=(ExpandTextView) findViewById(R.id.expand);    tv.setText("在平时的开发过程中,相信都会使用到多线程,在使用多线程时,大家也会遇到各种各样的问题,今天我们就来说说一个多线程的问题——线程中断。在java中启动线程非常容易,大多数情况下我是让一个线程执行完自己的任务然后自己停掉,但是有时候我们需要取消某个操作,比如你在网络下载时,有时候需要取消下载。实现线程的安全中断并不是一件容易的事情,因为Java并不支持安全快速中断线程的机制,这里估计很多同学就会说了,java不是提供了Thread.interrupt 方法中断线程吗,好吧,我们今天就从这个方法开始说起。");  }  @Override  public boolean onCreateOptionsMenu(Menu menu) {    // Inflate the menu; this adds items to the action bar if it is present.    getMenuInflater().inflate(R.menu.main, menu);    return true;  }  @Override  public boolean onOptionsItemSelected(MenuItem item) {    // Handle action bar item clicks here. The action bar will    // automatically handle clicks on the Home/Up button, so long    // as you specify a parent activity in AndroidManifest.xml.    int id = item.getItemId();    if (id == R.id.action_settings) {      return true;    }    return super.onOptionsItemSelected(item);  }}

Demo下载地址:

http://download.csdn.net/detail/yy471101598/9185623

0 0