Android开发:找出TextView里被点击处的字符和单词

原理,在TextView的onTouch事件里,取到点击的座标,再根据y座标,找出第几行,再根据行号,找出该行显示的字符串,然后根据x座标,计算点击处的字符。如果处理中文,找到即可,找英文单词的话,在该字符前后查找,看其是否属于同一个单词。
根据x座标行内查找这里,应该有更快的算法,因为我用的的最笨的方法,希望得到高人指点。


textView.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO 自动生成的方法存根
				switch(event.getAction())
				{
				case MotionEvent.ACTION_DOWN:
					float x=event.getX();
					float y=event.getY();
					//因为行设置行间距后,文本在顶部,空白在底部,加上一半的行间距,可以实现与文本垂直居中一样的效果
					y=y+textView.getLineSpacingExtra()/2-textView.getPaddingTop();
					//在顶部padding空白处点击
					if(y<0)
						return false;
					int singleLineHeight=textView.getLineHeight();
					StaticLayout layout=(StaticLayout)textView.getLayout();
				
					int lineNumber=Math.round(y/singleLineHeight)-1;
					if(lineNumber<0)
						lineNumber=0;
					if(lineNumber>textView.getLineCount()-1)
						lineNumber-=1;
					int start=layout.getLineStart(lineNumber);
					int end=layout.getLineEnd(lineNumber);
					
					String str=textView.getText().toString().substring(start, end);
				 	Paint paint=new Paint();
			    	paint.setTextSize(textView.getTextSize());//设置字符大小
			    	//单字节占宽度
			    	int sigleByteWidth=(int)paint.measureText("1", 0, 1);
					
			    	//减掉padding
			    	float realX=x-textView.getPaddingLeft();
			    	//在左侧padding空白处点击
			    	if(realX<0)
			    	{
			    		return false;
			    	}
			    	//字符串可能的最大长度
			    	//这里应该有更好更快的算法
			    	int maxLength=(int)Math.floor(realX/sigleByteWidth);
			    	//一般不会有字符显示超过两个1的宽度
			    	int miniLenth=maxLength/2;
			    	int strLength=str.length();
			    	for(int i=strLength;i>=miniLenth;i--)
			    	{
			    		//字符串显示的宽度
			    		float displayWidth=paint.measureText(str, 0, i);
			    		if(Math.abs(displayWidth-realX)90&&clickChar<97)||clickChar>122)
			    			{
			    				return false;
			    			}
			    			//取单词,这段只针对英文,中文需要海量词库,太复杂了,前后看是不是空格或符号
			    			StringBuilder sb=new StringBuilder();
			    			sb.append(str.substring(i-1,i));
			    			//查找前后的字符是否是同一个单词
			    			String strBefore=str.substring(0,i-1);
			    			String strAfter=str.substring(i,str.length());
			    			
			    			String strBeforeReverse=reverseStr(strBefore);
			    			Pattern p1=Pattern.compile("(^[a-zA-Z]+)");
			    			//正则
			    			Matcher m1=p1.matcher(strBeforeReverse);
			    			if(m1.find())
			    			{
			    				sb.insert(0, reverseStr(m1.group(1)));
			    			}
			    			
			    			m1=p1.matcher(strAfter);
			    			if(m1.find())
			    			{
			    				sb.append(m1.group(1));
			    			}
			    			System.out.println("点击单词"+sb.toString());
			    			break;
			    		}
			    	}
					break;
				}
				return false;
			}
		});

	/**
	 * 反转字符串
	 * @param s
	 * @return
	 */
	public String reverseStr(String s) {
		StringBuilder sb = new StringBuilder();
		for (int i = s.length() - 1; i >= 0; i--) {
			sb.append(s.charAt(i));
		}
		return sb.toString();
	}

© 2014, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接! 应用开发笔记

发表评论

电子邮件地址不会被公开。 必填项已用*标注