热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android自定义控件之TextView的展开与折叠

还是先描述一下需求,这个在其余的app中应该也经常看见,就是当一个段文字很长的时候,我们往往为了展示的时候节约展示的空间,需要将我们的文字折叠起来,如果用户想看里面的详细内容话,则需要用户去

还是先描述一下需求,这个在其余的app中应该也经常看见,就是当一个段文字很长的时候,我们往往为了展示的时候节约展示的空间,需要将我们的文字折叠起来,如果用户想看里面的详细内容话,则需要用户去点击一下改控件,然后TextView展开,显示全部的内容。由于我在本次的项目中有这个需求,所以我将其独立成了一个自定义控件,方便在以后的开发中能直接使用。下面是效果图


先来说说大致思路,其实也是很简单的一个控件,首先该控件是继承LinearLayout的,其中的布局文件包括一个TextView和一个下拉三角的ImageView,当用户在单击这个LinearLayout的时候,我会开一个子线程,让改线程睡20ms,睡完后再向主线程中发送一个handler,在主线程中重新设置一下TextView的显示行数,一次循环,直到显示全部内容为止,在折叠起来的时候设计思路也是一样的,当然在该控件中我用了一个isExp来标记该控件是否展开是否折叠。好了,大致的设计思路就是这样,很简单,接下来贴代码了,可以复制粘贴后直接使用


下面是布局文件




    

    


下面是页面处理的逻辑代码

package com.renrui.job.widget;

import com.renrui.job.R;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * 可折叠的TextView
 */
public class FoldTextView extends LinearLayout
{
	FoldTextViewHolder mFoldTextViewHolder;
	View myView;

	/**
	 * 真实行数
	 */
	int realLineCounts = 0;
	
	/**
	 * 默认行数
	 */
	int defaultLineCounts = 4;

	/**
	 * 真实高度
	 */
	int realHeight = 0;

	/**
	 * 折叠后的高度
	 */
	int foldHeight = 0;

	boolean isFirstLoad = true;

	/**
	 * Icon状态 展开动画
	 */
	RotateAnimation expIconAnimation;

	/**
	 * Icon状态 折叠动画
	 */
	RotateAnimation foldIconAnimation;

	/**
	 * 当前是否展开
	 */
	boolean isExp = false;
	
	/**
	 * 展开TextView
	 */
	final int TEXT_OPEN = 1;
	
	/**
	 * 关闭TextView
	 */
	final int TEXT_CLOSE = 2;

	Handler mHander = new Handler()
	{
		LayoutParams layoutParma;
		public void handleMessage(android.os.Message msg)
		{
			int lines = (Integer) msg.obj;
			switch (msg.what)
			{
			case TEXT_OPEN:	//打开,增加高度
				mFoldTextViewHolder.tvFold.setMaxLines(lines);
				break;
			case TEXT_CLOSE://关闭,减少高度
				mFoldTextViewHolder.tvFold.setMaxLines(lines);
				break;
			}
		};
	};

	public FoldTextView(Context context)
	{
		super(context);

		init();
	}

	public FoldTextView(Context context, AttributeSet attrs)
	{
		super(context, attrs);

		init();
	}

	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	public FoldTextView(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);

		init();
	}

	private void init()
	{
		LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
		myView = inflater.inflate(R.layout.view_widget_foldtextview, null);
		this.addView(myView, layoutParams);

		//设置小箭头展开时的旋转动画
		expIcOnAnimation= new RotateAnimation(0f, 180f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
		expIconAnimation.setDuration(300);
		expIconAnimation.setFillAfter(true);

		//设置小箭头关闭时的旋转动画
		foldIcOnAnimation= new RotateAnimation(180f, 0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
		foldIconAnimation.setDuration(300);
		foldIconAnimation.setFillAfter(true);

		mFoldTextViewHolder = new FoldTextViewHolder(this);
	}

	public void setText(String text)
	{
		mFoldTextViewHolder.tvFold.setText(text);

		ViewTreeObserver vto = mFoldTextViewHolder.tvFold.getViewTreeObserver();
		vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
		{
			@Override
			public void onGlobalLayout()
			{
				if (!isFirstLoad)
				{
					return;
				}

				//获取真实行数
				realLineCounts = mFoldTextViewHolder.tvFold.getLineCount();
				realHeight = mFoldTextViewHolder.tvFold.getMeasuredHeight();

				//如果真实行数大于默认的显示行数,则默认将其折叠起来  isExp为false
				if (realLineCounts > defaultLineCounts)
				{
					mFoldTextViewHolder.tvFold.setMaxLines(defaultLineCounts);
					mFoldTextViewHolder.tvFold.measure(0, 0);
					foldHeight = mFoldTextViewHolder.tvFold.getMeasuredHeight();
					mFoldTextViewHolder.ivFold.setVisibility(View.VISIBLE);

					mFoldTextViewHolder.tvFold.setOnClickListener(FoldOnclick);
					mFoldTextViewHolder.ivFold.setOnClickListener(FoldOnclick);
					isExp = false;
				}
				//如果真实行数小于默认行数,则直接展示出来。isExp为true;
				else
				{
					mFoldTextViewHolder.ivFold.setVisibility(View.GONE);
					isExp = true;
				}

				isFirstLoad = false;
			}
		});
	}

	View.OnClickListener FoldOnclick= new OnClickListener()
	{
		@Override
		public void onClick(View v)
		{
			if (isExp)
			{
				new Thread(new Runnable()
				{
					@Override
					public void run()
					{
						int endcount = realLineCounts;
						while(endcount-- > defaultLineCounts){
							Message msg = Message.obtain();
							msg.what = TEXT_CLOSE;
							msg.obj = endcount;
							mHander.sendMessage(msg);
							try
							{
								Thread.sleep(20);
							} catch (InterruptedException e)
							{
								e.printStackTrace();
							}
							
						}
					}
				}).start();
				
				mFoldTextViewHolder.ivFold.setAnimation(foldIconAnimation);
				foldIconAnimation.startNow();

				isExp = false;
			} else
			{
				new Thread(new Runnable()
				{
					
					@Override
					public void run()
					{
						int startcount = defaultLineCounts;
						while(startcount++  
 
好了  以上就是该控件的全部代码了,不多,但是有时候还是挺好用的

PS:由于本人技术有限,如果上面有错误的地方还希望大家指正,感激不尽




推荐阅读
author-avatar
祗想抱著伱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有