实施Scrollable Textview

时间:2017-12-20 12:16:55

标签: android textview

默认情况下,我需要显示TextView,就像我在下图中提到的三个点一样。

enter image description here

一旦我点击TextView,我需要展开并制作为可滚动的。(参考截图在这里添加)

enter image description here

任何在Android应用中执行此操作的帮助?

4 个答案:

答案 0 :(得分:1)

试试这个

<ScrollView
    android:id="@+id/scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:scrollbars="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ellipsize="end"
            android:maxLines="5"
            android:text="@string/str" />

    </LinearLayout>
</ScrollView>

和java代码

ScrollView scrollView = (ScrollView) findViewById(R.id.scroll);
         TextView textView = (TextView) findViewById(R.id.textview);

        scrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                textView.setEllipsize(null);
                textView.setMaxLines(100);
                return false;
            }
        });
  

输出

<强>正常

enter image description here

滚动时

enter image description here

答案 1 :(得分:0)

默认情况下,TextView应具有以下属性

  android:layout_height="30dp" 
  android:ellipsize="end" 
  android:maxLines="3"

在TextView的onTouchListener中,在运行时禁用ellipsize和maxLine属性,如下所示

 textView.setMaxLines(Integer.MAX_VALUE);
 textView.setEllipsize(null);
 textView.setScrollContainer(true); // make scrollable

那就是它。

答案 2 :(得分:0)

您可以创建如下所示的课程

class ExpandableTextView extends RelativeLayout 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;
private final String MORE = "more";
private final String LESS = "";
protected TextView mTv;
protected TextView mButton; // 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 Drawable mExpandDrawable;
private Drawable mCollapseDrawable;
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);
}

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;
}

@Override
public void onClick(View view) {
    if (mButton.getVisibility() != View.VISIBLE) {
        return;
    }

    mCollapsed = !mCollapsed;
    mButton.setText(mCollapsed ? MORE : LESS);

    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;

            if (mCollapsed) {
                mTv.setSingleLine(true);
                mButton.setText(MORE);
                mTv.setEllipsize(TextUtils.TruncateAt.END);
            } else {
                mButton.setText("");
                mTv.setSingleLine(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 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
    mButton.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);
    }
    mButton.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, @NonNull SparseBooleanArray collapsedStatus, int position) {
    mCollapsedStatus = collapsedStatus;
    mPosition = position;
    boolean isCollapsed = collapsedStatus.get(position, true);
    clearAnimation();
    mCollapsed = isCollapsed;
    //mButton.setText(mCollapsed ? MORE : LESS);
    setText(text);
    getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
    requestLayout();
}

@Nullable
public CharSequence getText() {
    if (mTv == null) {
        return "";
    }
    return mTv.getText();
}

public void setText(@Nullable CharSequence text) {
    mRelayout = true;
    mTv.setText(text);
    setVisibility(TextUtils.isEmpty(text) ? View.GONE : View.VISIBLE);
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    findViews();
}

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);
    mExpandDrawable = typedArray.getDrawable(R.styleable.ExpandableTextView_expandDrawable);
    mCollapseDrawable = typedArray.getDrawable(R.styleable.ExpandableTextView_collapseDrawable);

    if (mExpandDrawable == null) {
        mExpandDrawable = getDrawable(getContext(), R.drawable.ic_expand_more_black_24dp);
    }
    if (mCollapseDrawable == null) {
        mCollapseDrawable = getDrawable(getContext(), R.drawable.ic_expand_less_black_24dp);
    }

    typedArray.recycle();

    // default visibility is gone
    setVisibility(GONE);
}

private void findViews() {
    mButton = (TextView) getChildAt(0);
    //mButton.setText(mCollapsed ? MORE : LESS);
    mButton.setOnClickListener(this);
    mTv = (TextView) getChildAt(1);
    mTv.setOnClickListener(this);
}

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);
}

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;
    }
}

您可以在滚动视图中使用此类

<com.util.ExpandableTextView
                       android:id="@+id/tvDescription"
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent"
                        android:ellipsize="end"
                        android:maxLines="3"
                        android:text="@string/dummy_text"
                        app:animation_duration="1000" />

您可以使用

切换
tvDescription.toggle();

答案 3 :(得分:0)

textView.setMaxLines(Integer.MAX_VALUE); textView.setEllipsize(null); textView.setScrollContainer(true);

初始化TextView对象时在Java中使用它

你也可以通过ScrollView Tag获取XML。其中ScrollView和TextView的TextView子项必须是多行的