自訂的TextView,使部分內容擁有點擊事件,並在點擊內容上方出現對應的詞義等資訊,textview詞義

來源:互聯網
上載者:User

自訂的TextView,使部分內容擁有點擊事件,並在點擊內容上方出現對應的詞義等資訊,textview詞義

直接看:



上面圖中是一個TextView,註冊部分內容(KeyWord)是其擁有點擊事件,並通過計算KeyWord的座標,顯示KeyWord的想要的一些資訊


/** * 一個TextView中包含一個可以點擊的KeyWord(關鍵詞),並通過點擊關鍵詞,在對應關鍵詞位置正上方展示關鍵詞對應的解釋等邏輯 * @author DuGuang * */public class MainActivity extends Activity {private KeyWordTextView mTvKeyWord;private ShowHideView mShowHideView;private DotView mDotView;private int mStatusBarHeight; // 手機狀態列高度private int mTitleBarHeight;//手機標題列的高度private RelativeLayout mLlMain;private String mHide = "愛";private String mStartStr;//關鍵詞前面的欄位//private String mStartStr = null;private String mKeyWord = "love"; //關鍵詞private String mEndStr ;//關鍵詞後面的欄位//private String mEndStr = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initData();}/** * 初始化View */private void initView() {mTvKeyWord = (KeyWordTextView) findViewById(R.id.mTvKeyWord);mLlMain = (RelativeLayout) findViewById(R.id.mLlMain);mShowHideView = new ShowHideView(this);mDotView = new DotView(this);RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);mShowHideView.setLayoutParams(params);mDotView.setLayoutParams(params);mShowHideView.setVisibility(View.INVISIBLE);mLlMain.addView(mShowHideView);mLlMain.addView(mDotView);}/** * 填充資料 */private void initData() {mStartStr = "Whatever is worth doing is worth haha zhen de ke yi me, hao xi fan! Whatever is worth doing is worth haha zhen de ke yi me, hao xi fan! Whatever is worth doing is worth haha zhen de ke yi me, hao xi fan! Whatever is worth doing is worth haha zhen de ke yi me, hao xi fan! Whatever is worth doing is worth haha zhen de ke yi me, hao xi fan! Whatever is worth doing is worth haha zhen de ke yi me, hao xi fan! ";mEndStr = " Whatever is worth doing is worth doing well.";//這裡開啟子線程是為擷取狀態列和標題列的高度mTvKeyWord.post(new Runnable() {@Overridepublic void run() {getBarHeight();mTvKeyWord.setAllString(mStartStr, mKeyWord, mEndStr, mHide,mStatusBarHeight, mTitleBarHeight, mShowHideView,  mDotView);}});}/** * 擷取手機狀態列和標題列的高度 */private void getBarHeight() {Rect frame = new Rect();getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);Window window = getWindow();// 狀態列的高度mStatusBarHeight = frame.top;// 標題列跟狀態列的總體高度int contentViewTop = window.findViewById(Window.ID_ANDROID_CONTENT).getTop();// 標題列的高度:用上面的值減去狀態列的高度及為標題列高度mTitleBarHeight = contentViewTop - mStatusBarHeight;Log.i("dg", mStatusBarHeight + "..." + contentViewTop + "..."+ mTitleBarHeight);}}


/** * 一個TextView中包含一個可以點擊的KeyWord(關鍵詞),並通過點擊關鍵詞,在對應關鍵詞位置正上方展示關鍵詞對應的解釋等邏輯 *  * @author DuGuang * @date 2015.1.11 *  */public class KeyWordTextView extends TextView {protected static final String TAG = KeyWordTextView.class.getSimpleName();private Context mContext;private String mHide; // 關鍵詞的提示內容private ShowHideView mShowHideView;//show關鍵詞解釋private DotView mDotView;//畫一個圓點,效驗mShowHideView展示的位置是否正確private String mStartStr, mKeyWord, mEndStr;int mYStartTop;// 關鍵詞第一個字元頂部y座標int mYStartBottom;// 關鍵詞第一個字元底部y座標float mXStartLeft;// 關鍵詞第一個字元左邊x座標float mXStartRight;// 關鍵詞第一個字元右邊x座標int mYEndTop;// 關鍵詞最後一個字元頂部y座標int mYEndBottom;// 關鍵詞最後一個字元底部y座標float mXEndLeft;// 關鍵詞最後一個字元左邊x座標float mXEndRight;// 關鍵詞最後一個字元右邊x座標private Layout mLayout;private int mStartPosition; // 關鍵詞起始的位置private int mEndPosition; // 關鍵詞結束的位置private int mStatusBarHeight; //手機狀態列高度private int mTitleBarHeight;//手機標題列的高度private SpannableString mSpStr;//用於給KeyWord單獨加顏色和底線的類@SuppressLint("NewApi")public KeyWordTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext = context;}public KeyWordTextView(Context context, AttributeSet attrs) {super(context, attrs);this.mContext = context;}public KeyWordTextView(Context context) {super(context);this.mContext = context;}/** * 填充段落內容 *  * @param startStr *             * @param keyWord *            * @param endStr *             *//** * @param startStr * @param keyWord  * @param endStr * @param hide * @param mDotView  * @param mTitleBarHeight  * @param mShowHideView  *//** * @param startStr關鍵詞之前顯示的內容,如果沒有則傳null * @param keyWord關鍵詞,可以點擊的詞 * @param endStr關鍵詞之後顯示的內容,如果沒有則傳null * @param hide展示關鍵詞的解釋欄位 * @param statusBarHeight狀態列的高度 * @param titleBarHeight標題列的高度 * @param showHideView展示關鍵詞的View * @param dotView畫一個圓點,效驗mShowHideView展示的位置是否正確 */public void setAllString(String startStr, String keyWord, String endStr, String hide, int statusBarHeight, int titleBarHeight,ShowHideView showHideView, DotView dotView) {this.mStartStr = startStr;this.mKeyWord = keyWord;this.mEndStr = endStr;this.mHide = hide;this.mStatusBarHeight = statusBarHeight;this.mShowHideView = showHideView;this.mTitleBarHeight = titleBarHeight;this.mDotView = dotView;setKeyWordClick();initData();getTextLayout();}/** * 填充相關資料 */private void initData() {// 計算關鍵詞的起始位置mStartPosition = StringUtil.isNotEmpty(mStartStr) ? mStartStr.length() + 1 : 1;//計算關鍵詞結束所在位置mEndPosition = StringUtil.isNotEmpty(mEndStr) ?mStartPosition + mKeyWord.length()+1 : mStartPosition + mKeyWord.length() -1 ;setText(mStartStr);append(mSpStr);append(StringUtil.isNotEmpty(mEndStr) ? mEndStr : "");setMovementMethod(LinkMovementMethod.getInstance());// 相當於註冊關鍵詞的點擊事件(開始響應點擊事件)}/** * 擷取對應TextView的layout屬性 */private void getTextLayout() {// view變化監聽器ViewTreeObserver介紹ViewTreeObserver vto = getViewTreeObserver();vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {mLayout = getLayout();Rect bound = new Rect();int line = mLayout.getLineForOffset(mStartPosition);mLayout.getLineBounds(line, bound);mYStartTop = bound.top;mYStartBottom = bound.bottom;mXStartLeft = mLayout.getPrimaryHorizontal(mStartPosition);mXStartRight = mLayout.getSecondaryHorizontal(mStartPosition);}});}/** * 設定關鍵詞的點擊事件 */private void setKeyWordClick() {mSpStr = new SpannableString(mKeyWord);mSpStr.setSpan(new ClickableSpan() {@Overridepublic void updateDrawState(TextPaint ds) {super.updateDrawState(ds); ds.setColor(Color.BLUE); //設定文字顏色ds.setUnderlineText(true); // 設定底線}@Overridepublic void onClick(View widget) {Log.d("", "onTextClick........被點擊了");Log.i(TAG, "mYStartTop >>> " + mYStartTop);Log.i(TAG, "mYStartBottom >>> " + mYStartBottom);Log.i(TAG, "mXStartLeft >>> " + mXStartLeft);Log.i(TAG, "mXStartRight >>> " + mXStartRight);int[] location1 = new int[2];//getLocationInWindow(location1);getLocationOnScreen(location1);Log.i(TAG, "location1[0] >>> " + location1[0]);Log.i(TAG, "location1[1] >>> " + location1[1]);getKeyWordEndInfo();//RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);//params.leftMargin = 100;//params.topMargin = 100;//mdot.setLayoutParams(params);RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);params2.leftMargin = (int)(mXStartLeft+(mXEndRight - mXStartLeft)/2)- mShowHideView.getWidth()/2;params2.topMargin = (int)location1[1] - mStatusBarHeight - mTitleBarHeight + mYStartTop - mShowHideView.getHeight();mShowHideView.setLayoutParams(params2);mShowHideView.setPosition(mHide);mDotView.setPosition((int)(mXStartLeft+(mXEndRight - mXStartLeft)/2), (int)location1[1] - mStatusBarHeight - mTitleBarHeight + mYStartTop);}}, 0, mKeyWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}/** * 擷取關鍵詞最後一個字元的X,Y的相關資訊 */public void getKeyWordEndInfo(){mLayout = getLayout();Rect bound = new Rect();int line = mLayout.getLineForOffset(mEndPosition);mLayout.getLineBounds(line, bound);mYEndTop = bound.top;mYEndBottom = bound.bottom;mXEndLeft = mLayout.getPrimaryHorizontal(mEndPosition);mXEndRight = mLayout.getSecondaryHorizontal(mEndPosition);Log.i(TAG, "mYEndTop >>> " + mYEndTop);Log.i(TAG, "mYEndBottom >>> " + mYEndBottom);Log.i(TAG, "mXEndLeft >>> " + mXEndLeft);Log.i(TAG, "mXEndRight >>> " + mXEndRight);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);}}



/** * 點擊KeyWord後,顯示KeyWord的相關資訊的View * @author DuGuang * */public class ShowHideView extends LinearLayout{private Context mContext;private TextView mTvShowHide;@SuppressLint("NewApi")public ShowHideView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext = context;initView();}public ShowHideView(Context context, AttributeSet attrs) {super(context, attrs);this.mContext = context;initView();}public ShowHideView(Context context) {super(context);this.mContext = context;initView();}public void setPosition(String hide){mTvShowHide.setText(hide);setVisibility(View.VISIBLE);}/** * 填充自訂的XML布局 */public void initView() {View view = View.inflate(mContext, R.layout.item_popwin_start_hide,ShowHideView.this);mTvShowHide = (TextView) view.findViewById(R.id.tv_paly_hide);}}


/** * 畫一個點,用來效驗ShowHideView顯示的位置是否正確 * @author DuGuang * */public class DotView extends View{private static final String TAG = DotView.class.getSimpleName();private Context mContext;private float mX;private float mY;@SuppressLint("NewApi")public DotView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext = context;}public DotView(Context context, AttributeSet attrs) {super(context, attrs);this.mContext = context;}public DotView(Context context) {super(context);this.mContext = context;}public void setPosition(int x, int y){mX = x;mY = y;invalidate();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint  = new Paint();paint.setStyle(Style.FILL);paint.setStrokeWidth(20);paint.setColor(mContext.getResources().getColor(R.color.blue));Log.i(TAG, "mX >>> "+mX);Log.i(TAG, "mY >>> "+mY);canvas.drawPoint(mX, mY, paint);}}


Demo:http://download.csdn.net/detail/u011112840/8350491

Github地址:https://github.com/z56402344/CustomTextView

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.