实现的效果图如下 ;

点击查看详情把显示不全的数据显示出来 产接下里

接下来  我们来看下布局 

<?xml version="1.0" encoding="utf-8"?>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"    tools:context="com.example.wjkj.expendletextviewtest.MainActivity">            android:layout_width="match_parent"        android:id="@+id/expand_text_view"        app:maxCollapsedLines="2"        app:animDuration="200"        android:layout_height="wrap_content">                    android:id="@+id/expandable_text"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginTop="17dp"            android:ellipsize="end"            android:maxLines="4"            android:paddingLeft="10dp"            android:paddingRight="10dp"            android:textColor="@color/colorAccent"            android:textSize="14dp"            tools:text="这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文。" />                    android:id="@+id/expand_collapse"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="right|bottom"            android:layout_marginTop="9dp"            android:background="@android:color/transparent"            android:paddingRight="10dp"            android:text="查看详情>>"            android:textColor="@color/colorPrimary"            android:textSize="12sp" />    

布局文件相对比较简单   

java代码相对比较简单     下面上代码  

public class MainActivity extends AppCompatActivity {    ExpandableTextView expand_text_view;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        expand_text_view = findViewById(R.id.expand_text_view);        expand_text_view.setText("adasd asd         " +                "   asd asd asd asd asd asdasdasddasdasdasdasdasdddddsadsdasd s dasd as das dasd sad asd     asd asd asd " +                " ads asd asd as das ads asd d asd as dasd asd这里是内容信息正文," +                "这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文,这里是内容信息正文。 ");    }}

自定义view

class ExpandableTextView extends LinearLayout implements View.OnClickListener {    private static final String TAG = ExpandableTextView.class.getSimpleName();    /* The default number of lines */    private static final int MAX_COLLAPSED_LINES = 8;    /* The default animation duration */    private static final int DEFAULT_ANIM_DURATION = 300;    /* The default alpha value when the animation starts */    private static final float DEFAULT_ANIM_ALPHA_START = 0.7f;    protected TextView mTv;    protected TextView mTextView; // Button to expand/collapse    private boolean mRelayout;    private boolean mCollapsed = true; // Show short version as default.    private int mCollapsedHeight;    private int mTextHeightWithMaxLines;    private int mMaxCollapsedLines;    private int mMarginBetweenTxtAndBottom;    private int mAnimationDuration;    private float mAnimAlphaStart;    private boolean mAnimating;    /* Listener for callback */    private OnExpandStateChangeListener mListener;    /* For saving collapsed status when used in ListView */    private SparseBooleanArray mCollapsedStatus;    private int mPosition;    public ExpandableTextView(Context context) {        this(context, null);    }    public ExpandableTextView(Context context, AttributeSet attrs) {        super(context, attrs);        init(attrs);    }    @TargetApi(Build.VERSION_CODES.HONEYCOMB)    public ExpandableTextView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init(attrs);    }    @Override    public void setOrientation(int orientation) {        if (LinearLayout.HORIZONTAL == orientation) {            throw new IllegalArgumentException("ExpandableTextView only supports Vertical Orientation.");        }        super.setOrientation(orientation);    }    @Override    public void onClick(View view) {        if (mTextView.getVisibility() != View.VISIBLE) {            return;        }        mCollapsed = !mCollapsed;        if (mCollapsedStatus != null) {            mCollapsedStatus.put(mPosition, mCollapsed);        }        // mark that the animation is in progress        mAnimating = true;        Animation animation;        if (mCollapsed) {            animation = new ExpandCollapseAnimation(this, getHeight(), mCollapsedHeight);        } else {            animation = new ExpandCollapseAnimation(this, getHeight(), getHeight() +                    mTextHeightWithMaxLines - mTv.getHeight());        }        animation.setFillAfter(true);        animation.setAnimationListener(new Animation.AnimationListener() {            @Override            public void onAnimationStart(Animation animation) {                applyAlphaAnimation(mTv, mAnimAlphaStart);            }            @Override            public void onAnimationEnd(Animation animation) {                // clear animation here to avoid repeated applyTransformation() calls                clearAnimation();                // clear the animation flag                mAnimating = false;                // notify the listener                if (mListener != null) {                    mListener.onExpandStateChanged(mTv, !mCollapsed);                }            }            @Override            public void onAnimationRepeat(Animation animation) {            }        });        clearAnimation();        startAnimation(animation);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        // while an animation is in progress, intercept all the touch events to children to        // prevent extra clicks during the animation        return mAnimating;    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        findViews();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        // If no change, measure and return        if (!mRelayout || getVisibility() == View.GONE) {            super.onMeasure(widthMeasureSpec, heightMeasureSpec);            return;        }        mRelayout = false;        // Setup with optimistic case        // i.e. Everything fits. No button needed        mTextView.setVisibility(View.GONE);        mTv.setMaxLines(Integer.MAX_VALUE);        // Measure        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        // If the text fits in collapsed mode, we are done.        if (mTv.getLineCount() <= mMaxCollapsedLines) {            return;        }        // Saves the text height w/ max lines        mTextHeightWithMaxLines = getRealTextViewHeight(mTv);        // Doesn't fit in collapsed mode. Collapse text view as needed. Show        // button.        if (mCollapsed) {            mTv.setMaxLines(mMaxCollapsedLines);        }        mTextView.setVisibility(View.VISIBLE);        // Re-measure with new setup        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        if (mCollapsed) {            // Gets the margin between the TextView's bottom and the ViewGroup's bottom            mTv.post(new Runnable() {                @Override                public void run() {                    mMarginBetweenTxtAndBottom = getHeight() - mTv.getHeight();                }            });            // Saves the collapsed height of this ViewGroup            mCollapsedHeight = getMeasuredHeight();        }    }    public void setOnExpandStateChangeListener(@Nullable OnExpandStateChangeListener listener) {        mListener = listener;    }    public void setText(@Nullable CharSequence text) {        mRelayout = true;        mTv.setText(text);        setVisibility(TextUtils.isEmpty(text) ? View.GONE : View.VISIBLE);    }    public void setText(@Nullable CharSequence text, @NonNull SparseBooleanArray collapsedStatus, int position) {        mCollapsedStatus = collapsedStatus;        mPosition = position;        boolean isCollapsed = collapsedStatus.get(position, true);        clearAnimation();        mCollapsed = isCollapsed;        setText(text);        getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;        requestLayout();    }    @Nullable    public CharSequence getText() {        if (mTv == null) {            return "";        }        return mTv.getText();    }    private void init(AttributeSet attrs) {        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ExpandableTextView);        mMaxCollapsedLines = typedArray.getInt(R.styleable.ExpandableTextView_maxCollapsedLines, MAX_COLLAPSED_LINES);        mAnimationDuration = typedArray.getInt(R.styleable.ExpandableTextView_animDuration, DEFAULT_ANIM_DURATION);        mAnimAlphaStart = typedArray.getFloat(R.styleable.ExpandableTextView_animAlphaStart, DEFAULT_ANIM_ALPHA_START);        typedArray.recycle();        // enforces vertical orientation        setOrientation(LinearLayout.VERTICAL);        // default visibility is gone        setVisibility(GONE);    }    private void findViews() {        mTv = (TextView) findViewById(R.id.expandable_text);        mTv.setOnClickListener(this);        mTextView = (TextView) findViewById(R.id.expand_collapse);        mTextView.setOnClickListener(this);    }    private static boolean isPostHoneycomb() {        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;    }    private static boolean isPostLolipop() {        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;    }    @TargetApi(Build.VERSION_CODES.HONEYCOMB)    private static void applyAlphaAnimation(View view, float alpha) {        if (isPostHoneycomb()) {            view.setAlpha(alpha);        } else {            AlphaAnimation alphaAnimation = new AlphaAnimation(alpha, alpha);            // make it instant            alphaAnimation.setDuration(0);            alphaAnimation.setFillAfter(true);            view.startAnimation(alphaAnimation);        }    }    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    private static Drawable getDrawable(@NonNull Context context, @DrawableRes int resId) {        Resources resources = context.getResources();        if (isPostLolipop()) {            return resources.getDrawable(resId, context.getTheme());        } else {            return resources.getDrawable(resId);        }    }    private static int getRealTextViewHeight(@NonNull TextView textView) {        int textHeight = textView.getLayout().getLineTop(textView.getLineCount());        int padding = textView.getCompoundPaddingTop() + textView.getCompoundPaddingBottom();        return textHeight + padding;    }    class ExpandCollapseAnimation extends Animation {        private final View mTargetView;        private final int mStartHeight;        private final int mEndHeight;        public ExpandCollapseAnimation(View view, int startHeight, int endHeight) {            mTargetView = view;            mStartHeight = startHeight;            mEndHeight = endHeight;            setDuration(mAnimationDuration);        }        @Override        protected void applyTransformation(float interpolatedTime, Transformation t) {            final int newHeight = (int) ((mEndHeight - mStartHeight) * interpolatedTime + mStartHeight);            mTv.setMaxHeight(newHeight - mMarginBetweenTxtAndBottom);            if (Float.compare(mAnimAlphaStart, 1.0f) != 0) {                applyAlphaAnimation(mTv, mAnimAlphaStart + interpolatedTime * (1.0f - mAnimAlphaStart));            }            mTargetView.getLayoutParams().height = newHeight;            mTargetView.requestLayout();        }        @Override        public void initialize(int width, int height, int parentWidth, int parentHeight) {            super.initialize(width, height, parentWidth, parentHeight);        }        @Override        public boolean willChangeBounds() {            return true;        }    }    public interface OnExpandStateChangeListener {        /**         * Called when the expand/collapse animation has been finished         *         * @param textView   - TextView being expanded/collapsed         * @param isExpanded - true if the TextView has been expanded         */        void onExpandStateChanged(TextView textView, boolean isExpanded);    }
这样就能简单的实现我们想要的效果   至于其他类似布局 仅仅在此基础上做稍微改动即可  

更多相关文章

  1. android sign签名
  2. Android实现KSOAP2访问WebService
  3. Android获取应用信息判断网络连接返回桌面及卸载apk结束进程等的
  4. Android获取系统储存以及内存信息的方法(二)
  5. android常用adb快捷命令一览表
  6. Flutter开发中问题汇总贴(持续更新中)
  7. Android(安卓)系统信息获取(CPU,RAM,ROM,Battery,SD-card,版本等)
  8. 【报错问题】 - React native Android(安卓)Invariant Violation
  9. android 将一些信息保存到本地,以后更新版本或者替换之后,数据在新

随机推荐

  1. Android媒体库使用分组查询
  2. android:background="?attr/colorPrimary
  3. android APP隐私政策弹框的实现代码实例
  4. Android(安卓)11适配指南之Toast解析
  5. Android多线程
  6. Android正确获取屏幕像素和密度等
  7. Android:Android开发首先要做的工作
  8. Android(安卓)学习资源-博客篇
  9. Android进阶知识——Android线程和线程池
  10. 2011.07.08(3)——— android AlarmManager