今天要实现的功能就是点击上图的向下箭头,展现更多的文字,变成下图的样子。
实现的思路就是:有两个textview,一个显示短文本,一个显示长文本,通过点击箭头,动态的显示哪个textview.
怎么做?
我们需要自定义一个布局,继承RelativeLayout。
package com.example.demo.expandaletextview;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* Created by zj on 2015/8/21.
* <p/>
* you can set the textview's content by {@link #setContent(String)}
* you can set the color of textview's content by {@link #setContentColor(int)},the defaultValue od color is Black.
* you can set the textsize of textview's content by {@link #setContentColor(int)},the defaultValue od textsize is 15.
* you can set the updrawableId or downdrawableId by {@link #setUpdrawableId(int),#setDowndrawableId(int)}.
*/
public class ExpandaleTextView extends RelativeLayout {
private static final String TAG = "ExpandaleTextView";
private static final boolean DEBUG = true;
private int updrawableId, downdrawableId;
/**
* 字体大小,默认为15
*/
private float textShowSize;
/**
* 字体颜色.默认为黑色
*/
private int textShowColor;
/**
* 显示文本
*/
private String textShow;
/**
* 一开始只显示文本的最大行数,默认为5
*/
private int shortLines;
private TextView tv_short, tv_long;
/**
* 箭头
*/
private ImageView iv_arrow;
private FrameLayout fl;
/**
* 是否可扩展
*/
private boolean isExpandale = false;
private onArrowClickListener onArrowClickListener;
public ExpandaleTextView(Context context) {
this(context, null);
}
public ExpandaleTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ExpandaleTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initContentView(context, attrs);
}
/**
* 初始化两个textView的显示
*/
private void init() {
int shortHeight = tv_short.getHeight();
int longHeight = tv_long.getHeight();
//获取两个textView的高度,如果shortHeight的高度>=longHeight,则tv_short已经展示了所有的文字,把箭头隐藏掉,否则显示箭头
if (shortHeight >= longHeight) {
tv_long.setVisibility(GONE);
iv_arrow.setVisibility(GONE);
} else {
tv_long.setVisibility(GONE);
iv_arrow.setVisibility(VISIBLE);
}
}
private void initContentView(Context context, AttributeSet attrs) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ExpandaleTextView);
updrawableId = array.getResourceId(R.styleable.ExpandaleTextView_ExpandaleUpDrawable, R.mipmap.icon_detailhide);
downdrawableId = array.getResourceId(R.styleable.ExpandaleTextView_ExpandaleDownDrawable, R.mipmap.icon_detailshow);
textShow = array.getString(R.styleable.ExpandaleTextView_TextShow);
textShowColor = array.getColor(R.styleable.ExpandaleTextView_TextShowColor, Color.parseColor("#000000"));
textShowSize = array.getDimension(R.styleable.ExpandaleTextView_TextShowSize, 15);
shortLines = array.getInt(R.styleable.ExpandaleTextView_Shortlines, 5);
array.recycle();
View view = LayoutInflater.from(context).inflate(R.layout.expandale_textview, null);
tv_short = (TextView) view.findViewById(R.id.tv_short);
tv_long = (TextView) view.findViewById(R.id.tv_long);
iv_arrow = (ImageView) view.findViewById(R.id.iv_arrow);
fl = (FrameLayout) view.findViewById(R.id.fl);
if (!TextUtils.isEmpty(textShow)) {
setContent(textShow);
setContentSize(textShowSize);
setContentColor(textShowColor);
setShortLines(shortLines);
}
iv_arrow.setBackgroundDrawable(getResources().getDrawable(downdrawableId));
addView(view);
}
/**
* 设置一开始文本显示的行数
* @param shortLines
*/
public void setShortLines(int shortLines) {
this.shortLines = shortLines;
tv_short.setMaxLines(this.shortLines);
}
/**
* 设置文本的字体大小
*
* @param textShowSize
*/
public void setContentSize(float textShowSize) {
this.textShowSize = textShowSize;
tv_short.setTextSize(this.textShowSize);
tv_long.setTextSize(this.textShowSize);
}
/**
* 设置文本的颜色
*
* @param textShowColor
*/
public void setContentColor(int textShowColor) {
this.textShowColor = textShowColor;
tv_short.setTextColor(this.textShowColor);
tv_long.setTextColor(this.textShowColor);
}
/**
* 设置展开后的显示的图标
*
* @param updrawableId
*/
public void setUpdrawableId(int updrawableId) {
this.updrawableId = updrawableId;
}
/**
* 设置未展开时显示的图片
*
* @param downdrawableId
*/
public void setDowndrawableId(int downdrawableId) {
this.downdrawableId = downdrawableId;
}
/**
* 设置文本,以及点击监听事件
*
* @param content
*/
public void setContent(String content) {
tv_short.setText(content);
tv_long.setText(content);
tv_short.setMaxLines(shortLines);
//用来观察两个textview的高度
ViewTreeObserver observer = fl.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
fl.getViewTreeObserver().removeOnGlobalLayoutListener(this);
else
fl.getViewTreeObserver().removeGlobalOnLayoutListener(this);
init();
}
});
//设置点击的监听事件,动态的显示应该展现的textView和arrow图标
iv_arrow.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
isExpandale = !isExpandale;
if (isExpandale) {
if (onArrowClickListener != null) {
onArrowClickListener.onDownClickListener();
}
iv_arrow.setBackgroundDrawable(getResources().getDrawable(updrawableId));
tv_short.setVisibility(GONE);
tv_long.setVisibility(VISIBLE);
} else {
if (onArrowClickListener != null) {
onArrowClickListener.onUpClickListener();
}
iv_arrow.setBackgroundDrawable(getResources().getDrawable(downdrawableId));
tv_short.setVisibility(VISIBLE);
tv_long.setVisibility(GONE);
}
}
});
}
/**
* 设置点击的回调接口
*
* @param onArrowClickListener
*/
public void setOnArrowClickListener(onArrowClickListener onArrowClickListener) {
this.onArrowClickListener = onArrowClickListener;
}
/**
* 点击的回调接口
*/
public interface onArrowClickListener {
void onUpClickListener();
void onDownClickListener();
}
}
我们自定义的ExpandaleTextView的一些属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ExpandaleTextView">
<attr name="ExpandaleUpDrawable" format="reference"/>
<attr name="ExpandaleDownDrawable" format="reference"/>
<attr name="TextShow" format="string"/>
<attr name="Shortlines" format="integer"/>
<attr name="TextShowSize" format="dimension"/>
<attr name="TextShowColor" format="color"/>
</declare-styleable>
</resources>
我们自定义的ExpandaleTextView的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/fl"
android:layout_width="match_parent"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_short"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:textSize="26sp" />
<TextView
android:id="@+id/tv_long"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="26sp" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center">
<ImageView
android:id="@+id/iv_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
</LinearLayout>
接下来就是activity_main的布局代码,很简单只有一个ExpandaleTextView:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.demo.expandaletextview.ExpandaleTextView
android:id="@+id/etv"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
最后就是MainActivity,展示一下如何使用自定义的ExpandaleTextView:
package com.example.demo.expandaletextview;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
private ExpandaleTextView etv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etv = (ExpandaleTextView) findViewById(R.id.etv);
String str = "今天我们要实现的功能就是可扩展的TextView,点击向下箭头显示更多内容,点击向上箭头回到原来的样子,实现了可以设置文本的字体和颜色,以及箭头的背景图片,并且增加了点击的回调接口,欢迎大家体验";
etv.setContent(str);
etv.setContentColor(R.color.text_blue_color);
etv.setContentSize(20);
etv.setShortLines(2);
etv.setOnArrowClickListener(new ExpandaleTextView.onArrowClickListener() {
@Override
public void onUpClickListener() {
Toast.makeText(getApplicationContext(), "you click the updrawable", Toast.LENGTH_SHORT).show();
}
@Override
public void onDownClickListener() {
Toast.makeText(getApplicationContext(), "you click the downdrawable", Toast.LENGTH_SHORT).show();
}
});
}
}
最后附上demo:
Expandale TextView Demo