Android实现简单的ExpandTextview

最近工作中需要使用到ExpandTextview,因为没有原生的控件可以使用,GitHub上面有没有找到合适的,那就自己造一个轮子吧:)

最终要实现的效果就是TextView的行数最大不超过两行,大于两行的会有下拉按钮可以让用户展开或者收缩内容,如果本来的内容就在两行以下的,就隐藏下拉按钮,行数保持原有的样子。最后我们希望达到的效果是这样的:

Android实现简单的ExpandTextview_第1张图片
收缩的样子
Android实现简单的ExpandTextview_第2张图片
展开的样子

内容超过两行可以收缩或者展开,内容没有超过两行的则保持不变。


因为我的实际需求是要在列表中展示内容,那么就先来创建一个列表:

  • activity_main.xml:



    

  • item_expand.xml:



    

        

        
    


布局完成了之后,那么接下来我们的主要关注点就是adapter里面的实现了,自定义一个CustomAdapter,并在binding方法中实现我们的逻辑代码:

package com.lxy.mew.expandtextview.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.lxy.mew.expandtextview.R;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * Created by master on 2017/4/29.
 */
public class CustomAdapter extends RecyclerView.Adapter
{

    private Context context;
    private List datas = new ArrayList<>();


    public CustomAdapter(Context context)
    {
        this.context = context;
    }

    public void setDatas(List datas)
    {
        this.datas = datas;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_expand, parent, false));
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position)
    {

        String item = datas.get(position);
        holder.tvContent.setText(item);

        final View.OnClickListener listener = new View.OnClickListener()
        {
            boolean isExpand;//设置是否展开的标记

            @Override
            public void onClick(View v)
            {
                if (isExpand)
                {
                    holder.tvContent.setMaxLines(2);//如果当前是展开的,则设置为闭合
                    holder.ivArrow.setRotation(0);//箭头重置为向下的状态
                    isExpand = false;
                } else
                {
                    holder.tvContent.setMaxLines(Integer.MAX_VALUE);//如果是闭合的,则展开
                    holder.ivArrow.setRotation(180);//箭头设置为向上
                    isExpand = true;
                }

            }
        };
        holder.tvContent.post(new Runnable()
        {
            @Override
            public void run()
            {
                /**
                 * 在子线程中获取textview的行数,等页面加载完成之后才能取到行数
                 */
                int lineCount = holder.tvContent.getLineCount();
                if (lineCount > 2)//如果行数大于2,就让textview闭合
                {
                    holder.tvContent.setMaxLines(2);
                    holder.viewContainer.setOnClickListener(listener);//可以相应点击事件
                    holder.ivArrow.setVisibility(View.VISIBLE);
                } else
                {
                    holder.viewContainer.setOnClickListener(null);//行数没有超过两行,保持原状,无需改变
                    holder.ivArrow.setVisibility(View.GONE);//让箭头消失
                }
            }
        });

    }

    @Override
    public int getItemCount()
    {
        return datas.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder
    {

        View viewContainer;
        TextView tvContent;
        ImageView ivArrow;

        ViewHolder(View itemView)
        {
            super(itemView);

            viewContainer = itemView.findViewById(R.id.view_item_container);
            tvContent = (TextView) itemView.findViewById(R.id.tv_item_content);
            ivArrow = (ImageView) itemView.findViewById(R.id.iv_item_arrow);

        }
    }
}

个人感觉主要用到的知识点就是获取TextView行数,因为lineCount属性是在UI绘制加载完成之后才会有值的,所以不能在主线程中getLineCount();那样取到的值永远都是0.

整个实现思路大致就是这样,当然可以自己根据需求扩展和改进它的功能。
源码

你可能感兴趣的:(Android实现简单的ExpandTextview)