wordpress多站点优缺点,七台河新闻联播2022视频,电子商务网站的建设论文,wordpress增加板块文章目录 前言一、效果图二、实现步骤1.OnSelectListener2.SelectionInfo类3.TextLayoutUtil类4.复制弹框的xml布局5.弹框背景Drawable6.倒三角Drawable7.复制工具类8.调用 总结 前言
根据时代进步#xff0c;那些干产品的也叼砖起来了#xff0c;今天就遇到一个需求#x… 文章目录 前言一、效果图二、实现步骤1.OnSelectListener2.SelectionInfo类3.TextLayoutUtil类4.复制弹框的xml布局5.弹框背景Drawable6.倒三角Drawable7.复制工具类8.调用 总结 前言
根据时代进步那些干产品的也叼砖起来了今天就遇到一个需求需要对TextView的文案进行自由选择复制不怕我们是勇敢牛牛。 一、效果图 二、实现步骤
1.OnSelectListener
public interface OnSelectListener {void onTextSelected(CharSequence content);
}
2.SelectionInfo类
代码如下示例
public class SelectionInfo {public int mStart;public int mEnd;public String mSelectionContent;
}
3.TextLayoutUtil类
package com.example.merchant.utils;import android.content.Context;
import android.text.Layout;
import android.widget.TextView;public class TextLayoutUtil {public static int getScreenWidth(Context context) {return context.getResources().getDisplayMetrics().widthPixels;}public static int getPreciseOffset(TextView textView, int x, int y) {Layout layout textView.getLayout();if (layout ! null) {int topVisibleLine layout.getLineForVertical(y);int offset layout.getOffsetForHorizontal(topVisibleLine, x);int offsetX (int) layout.getPrimaryHorizontal(offset);if (offsetX x) {return layout.getOffsetToLeftOf(offset);} else {return offset;}} else {return -1;}}public static int getHysteresisOffset(TextView textView, int x, int y, int previousOffset) {final Layout layout textView.getLayout();if (layout null) return -1;int line layout.getLineForVertical(y);if (isEndOfLineOffset(layout, previousOffset)) {// we have to minus one from the offset so that the code below to find// the previous line can work correctly.int left (int) layout.getPrimaryHorizontal(previousOffset - 1);int right (int) layout.getLineRight(line);int threshold (right - left) / 2; // half the width of the last characterif (x right - threshold) {previousOffset - 1;}}final int previousLine layout.getLineForOffset(previousOffset);final int previousLineTop layout.getLineTop(previousLine);final int previousLineBottom layout.getLineBottom(previousLine);final int hysteresisThreshold (previousLineBottom - previousLineTop) / 2;if (((line previousLine 1) ((y - previousLineBottom) hysteresisThreshold)) || ((line previousLine - 1) ((previousLineTop- y) hysteresisThreshold))) {line previousLine;}int offset layout.getOffsetForHorizontal(line, x);if (offset textView.getText().length() - 1) {if (isEndOfLineOffset(layout, offset 1)) {int left (int) layout.getPrimaryHorizontal(offset);int right (int) layout.getLineRight(line);int threshold (right - left) / 2; // half the width of the last characterif (x right - threshold) {offset 1;}}}return offset;}private static boolean isEndOfLineOffset(Layout layout, int offset) {return offset 0 layout.getLineForOffset(offset) layout.getLineForOffset(offset - 1) 1;}public static int dp2px(Context context, float dpValue) {final float scale context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale 0.5f);}
}
4.复制弹框的xml布局
?xml version1.0 encodingutf-8?
RelativeLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthwrap_contentandroid:layout_heightmatch_parentLinearLayoutandroid:idid/linearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgrounddrawable/bg_operate_windowandroid:orientationhorizontalandroid:paddingLeft5dpandroid:paddingRight5dpTextViewandroid:idid/tv_copystylestyle/OperateTextViewandroid:textstring/Copy /TextViewandroid:idid/tv_select_allstylestyle/OperateTextViewandroid:textstring/SelectAll //LinearLayoutImageViewandroid:idid/iv_triangleandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_belowid/linearLayoutandroid:layout_centerHorizontaltrueandroid:srcdrawable/triangle_down /
/RelativeLayout5.弹框背景Drawable
?xml version1.0 encodingutf-8?shape xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:shaperectanglecorners android:radius5dp /solid android:color#454545 //shape6.倒三角Drawable
?xml version1.0 encodingutf-8?
layer-list xmlns:androidhttp://schemas.android.com/apk/res/androiditemrotateandroid:fromDegrees45android:pivotX135%android:pivotY15%shape android:shaperectanglesizeandroid:width16dpandroid:height16dp /solid android:color#454545 //shape/rotate/item
/layer-list7.复制工具类
package com.example.merchant.utils;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.text.Layout;
import android.text.Spannable;
import android.text.Spanned;
import android.text.style.BackgroundColorSpan;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.PopupWindow;
import android.widget.TextView;import androidx.annotation.ColorInt;import com.example.merchant.R;/*** 复制utils*/
public class SelectableTextHelper {private final static int DEFAULT_SELECTION_LENGTH 1;private static final int DEFAULT_SHOW_DURATION 100;private CursorHandle mStartHandle;private CursorHandle mEndHandle;private OperateWindow mOperateWindow;private SelectionInfo mSelectionInfo new SelectionInfo();private OnSelectListener mSelectListener;private Context mContext;private TextView mTextView;private Spannable mSpannable;private int mTouchX;private int mTouchY;private int mSelectedColor;private int mCursorHandleColor;private int mCursorHandleSize;private BackgroundColorSpan mSpan;private boolean isHideWhenScroll;private boolean isHide true;private ViewTreeObserver.OnPreDrawListener mOnPreDrawListener;ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener;public SelectableTextHelper(Builder builder) {mTextView builder.mTextView;mContext mTextView.getContext();mSelectedColor builder.mSelectedColor;mCursorHandleColor builder.mCursorHandleColor;mCursorHandleSize TextLayoutUtil.dp2px(mContext, builder.mCursorHandleSizeInDp);init();}private void init() {mTextView.setText(mTextView.getText(), TextView.BufferType.SPANNABLE);mTextView.setOnLongClickListener(new View.OnLongClickListener() {Overridepublic boolean onLongClick(View v) {showSelectView(mTouchX, mTouchY);return true;}});mTextView.setOnTouchListener(new View.OnTouchListener() {Overridepublic boolean onTouch(View v, MotionEvent event) {mTouchX (int) event.getX();mTouchY (int) event.getY();return false;}});mTextView.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View v) {resetSelectionInfo();hideSelectView();}});mTextView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {Overridepublic void onViewAttachedToWindow(View v) {}Overridepublic void onViewDetachedFromWindow(View v) {destroy();}});mOnPreDrawListener new ViewTreeObserver.OnPreDrawListener() {Overridepublic boolean onPreDraw() {if (isHideWhenScroll) {isHideWhenScroll false;postShowSelectView(DEFAULT_SHOW_DURATION);}return true;}};mTextView.getViewTreeObserver().addOnPreDrawListener(mOnPreDrawListener);mOnScrollChangedListener new ViewTreeObserver.OnScrollChangedListener() {Overridepublic void onScrollChanged() {if (!isHideWhenScroll !isHide) {isHideWhenScroll true;if (mOperateWindow ! null) {mOperateWindow.dismiss();}if (mStartHandle ! null) {mStartHandle.dismiss();}if (mEndHandle ! null) {mEndHandle.dismiss();}}}};mTextView.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener);mOperateWindow new OperateWindow(mContext);}private void postShowSelectView(int duration) {mTextView.removeCallbacks(mShowSelectViewRunnable);if (duration 0) {mShowSelectViewRunnable.run();} else {mTextView.postDelayed(mShowSelectViewRunnable, duration);}}private final Runnable mShowSelectViewRunnable new Runnable() {Overridepublic void run() {if (isHide) return;if (mOperateWindow ! null) {mOperateWindow.show();}if (mStartHandle ! null) {showCursorHandle(mStartHandle);}if (mEndHandle ! null) {showCursorHandle(mEndHandle);}}};private void hideSelectView() {isHide true;if (mStartHandle ! null) {mStartHandle.dismiss();}if (mEndHandle ! null) {mEndHandle.dismiss();}if (mOperateWindow ! null) {mOperateWindow.dismiss();}}private void resetSelectionInfo() {mSelectionInfo.mSelectionContent null;if (mSpannable ! null mSpan ! null) {mSpannable.removeSpan(mSpan);mSpan null;}}private void showSelectView(int x, int y) {hideSelectView();resetSelectionInfo();isHide false;if (mStartHandle null) mStartHandle new CursorHandle(true);if (mEndHandle null) mEndHandle new CursorHandle(false);int startOffset TextLayoutUtil.getPreciseOffset(mTextView, x, y);int endOffset startOffset DEFAULT_SELECTION_LENGTH;if (mTextView.getText() instanceof Spannable) {mSpannable (Spannable) mTextView.getText();}if (mSpannable null || startOffset mTextView.getText().length()) {return;}selectText(startOffset, endOffset);showCursorHandle(mStartHandle);showCursorHandle(mEndHandle);mOperateWindow.show();}private void showCursorHandle(CursorHandle cursorHandle) {Layout layout mTextView.getLayout();int offset cursorHandle.isLeft ? mSelectionInfo.mStart : mSelectionInfo.mEnd;cursorHandle.show((int) layout.getPrimaryHorizontal(offset), layout.getLineBottom(layout.getLineForOffset(offset)));}private void selectText(int startPos, int endPos) {if (startPos ! -1) {mSelectionInfo.mStart startPos;}if (endPos ! -1) {mSelectionInfo.mEnd endPos;}if (mSelectionInfo.mStart mSelectionInfo.mEnd) {int temp mSelectionInfo.mStart;mSelectionInfo.mStart mSelectionInfo.mEnd;mSelectionInfo.mEnd temp;}if (mSpannable ! null) {if (mSpan null) {mSpan new BackgroundColorSpan(mSelectedColor);}mSelectionInfo.mSelectionContent mSpannable.subSequence(mSelectionInfo.mStart, mSelectionInfo.mEnd).toString();mSpannable.setSpan(mSpan, mSelectionInfo.mStart, mSelectionInfo.mEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);if (mSelectListener ! null) {mSelectListener.onTextSelected(mSelectionInfo.mSelectionContent);}}}public void setSelectListener(OnSelectListener selectListener) {mSelectListener selectListener;}public void destroy() {mTextView.getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener);mTextView.getViewTreeObserver().removeOnPreDrawListener(mOnPreDrawListener);resetSelectionInfo();hideSelectView();mStartHandle null;mEndHandle null;mOperateWindow null;}/*** Operate windows : copy, select all*/private class OperateWindow {private PopupWindow mWindow;private int[] mTempCoors new int[2];private int mWidth;private int mHeight;public OperateWindow(final Context context) {View contentView LayoutInflater.from(context).inflate(R.layout.layout_operate_windows2, null);contentView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));mWidth contentView.getMeasuredWidth();mHeight contentView.getMeasuredHeight();mWindow new PopupWindow(contentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, false);mWindow.setClippingEnabled(false);TextView tv_copy contentView.findViewById(R.id.tv_copy);TextView tv_select_all contentView.findViewById(R.id.tv_select_all);tv_copy.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View v) {//复制点击实现功能AppTk.Companion.showTimeDailog(mSelectionInfo.mSelectionContent, mContext);if (mSelectListener ! null) {mSelectListener.onTextSelected(mSelectionInfo.mSelectionContent);}SelectableTextHelper.this.resetSelectionInfo();SelectableTextHelper.this.hideSelectView();}});tv_select_all.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View v) {hideSelectView();selectText(0, mTextView.getText().length());isHide false;showCursorHandle(mStartHandle);showCursorHandle(mEndHandle);mOperateWindow.show();}});}public void show() {mTextView.getLocationInWindow(mTempCoors);Layout layout mTextView.getLayout();int posX (int) layout.getPrimaryHorizontal(mSelectionInfo.mStart) mTempCoors[0];int posY layout.getLineTop(layout.getLineForOffset(mSelectionInfo.mStart)) mTempCoors[1] - mHeight - 16;if (posX 0) posX 16;if (posY 0) posY 16;if (posX mWidth TextLayoutUtil.getScreenWidth(mContext)) {posX TextLayoutUtil.getScreenWidth(mContext) - mWidth - 16;}if (Build.VERSION.SDK_INT Build.VERSION_CODES.LOLLIPOP) {mWindow.setElevation(8f);}mWindow.showAtLocation(mTextView, Gravity.NO_GRAVITY, posX, posY);}public void dismiss() {mWindow.dismiss();}public boolean isShowing() {return mWindow.isShowing();}}private class CursorHandle extends View {private PopupWindow mPopupWindow;private Paint mPaint;private int mCircleRadius mCursorHandleSize / 2;private int mWidth mCircleRadius * 2;private int mHeight mCircleRadius * 2;private int mPadding 25;private boolean isLeft;public CursorHandle(boolean isLeft) {super(mContext);this.isLeft isLeft;mPaint new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(mCursorHandleColor);mPopupWindow new PopupWindow(this);mPopupWindow.setClippingEnabled(false);mPopupWindow.setWidth(mWidth mPadding * 2);mPopupWindow.setHeight(mHeight mPadding / 2);invalidate();}Overrideprotected void onDraw(Canvas canvas) {canvas.drawCircle(mCircleRadius mPadding, mCircleRadius, mCircleRadius, mPaint);if (isLeft) {canvas.drawRect(mCircleRadius mPadding, 0, mCircleRadius * 2 mPadding, mCircleRadius, mPaint);} else {canvas.drawRect(mPadding, 0, mCircleRadius mPadding, mCircleRadius, mPaint);}}private int mAdjustX;private int mAdjustY;private int mBeforeDragStart;private int mBeforeDragEnd;Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:mBeforeDragStart mSelectionInfo.mStart;mBeforeDragEnd mSelectionInfo.mEnd;mAdjustX (int) event.getX();mAdjustY (int) event.getY();break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:mOperateWindow.show();break;case MotionEvent.ACTION_MOVE:mOperateWindow.dismiss();int rawX (int) event.getRawX();int rawY (int) event.getRawY();update(rawX mAdjustX - mWidth, rawY mAdjustY - mHeight);break;}return true;}private void changeDirection() {isLeft !isLeft;invalidate();}public void dismiss() {mPopupWindow.dismiss();}private int[] mTempCoors new int[2];public void update(int x, int y) {mTextView.getLocationInWindow(mTempCoors);int oldOffset;if (isLeft) {oldOffset mSelectionInfo.mStart;} else {oldOffset mSelectionInfo.mEnd;}y - mTempCoors[1];int offset TextLayoutUtil.getHysteresisOffset(mTextView, x, y, oldOffset);if (offset ! oldOffset) {resetSelectionInfo();if (isLeft) {if (offset mBeforeDragEnd) {CursorHandle handle getCursorHandle(false);changeDirection();handle.changeDirection();mBeforeDragStart mBeforeDragEnd;selectText(mBeforeDragEnd, offset);handle.updateCursorHandle();} else {selectText(offset, -1);}updateCursorHandle();} else {if (offset mBeforeDragStart) {CursorHandle handle getCursorHandle(true);handle.changeDirection();changeDirection();mBeforeDragEnd mBeforeDragStart;selectText(offset, mBeforeDragStart);handle.updateCursorHandle();} else {selectText(mBeforeDragStart, offset);}updateCursorHandle();}}}private void updateCursorHandle() {mTextView.getLocationInWindow(mTempCoors);Layout layout mTextView.getLayout();if (isLeft) {mPopupWindow.update((int) layout.getPrimaryHorizontal(mSelectionInfo.mStart) - mWidth getExtraX(),layout.getLineBottom(layout.getLineForOffset(mSelectionInfo.mStart)) getExtraY(), -1, -1);} else {mPopupWindow.update((int) layout.getPrimaryHorizontal(mSelectionInfo.mEnd) getExtraX(),layout.getLineBottom(layout.getLineForOffset(mSelectionInfo.mEnd)) getExtraY(), -1, -1);}}public void show(int x, int y) {mTextView.getLocationInWindow(mTempCoors);int offset isLeft ? mWidth : 0;mPopupWindow.showAtLocation(mTextView, Gravity.NO_GRAVITY, x - offset getExtraX(), y getExtraY());}public int getExtraX() {return mTempCoors[0] - mPadding mTextView.getPaddingLeft();}public int getExtraY() {return mTempCoors[1] mTextView.getPaddingTop();}}private CursorHandle getCursorHandle(boolean isLeft) {if (mStartHandle.isLeft isLeft) {return mStartHandle;} else {return mEndHandle;}}public static class Builder {private TextView mTextView;private int mCursorHandleColor 0xFF1379D6;private int mSelectedColor 0xFFAFE1F4;private float mCursorHandleSizeInDp 24;public Builder(TextView textView) {mTextView textView;}public Builder setCursorHandleColor(ColorInt int cursorHandleColor) {mCursorHandleColor cursorHandleColor;return this;}public Builder setCursorHandleSizeInDp(float cursorHandleSizeInDp) {mCursorHandleSizeInDp cursorHandleSizeInDp;return this;}public Builder setSelectedColor(ColorInt int selectedBgColor) {mSelectedColor selectedBgColor;return this;}public SelectableTextHelper build() {return new SelectableTextHelper(this);}}
}
8.调用
private var mSelectableTextHelper: SelectableTextHelper? null//实例化
//text为文案
mSelectableTextHelper SelectableTextHelper.Builder(text).setSelectedColor(Color.parseColor(#afe1f4)).setCursorHandleSizeInDp(20f).setCursorHandleColor(Color.parseColor(#0d7aff)).build()总结
感觉东西是有点多但比较实用而且直接复制去就可以用自己写主要费大脑不是。