Edittext响应onclick,由于click事件被onTouchEvent拦截,所以通过设置touch事件监听处理
// et_more.setOnTouchListener(new OnTouchListener() { // @Override // public boolean onTouch(View v, MotionEvent event) { // if(MotionEvent.ACTION_UP==event.getAction()){ // .... } // return false; // } // });
EditText设置enable为false时,不响应ontouch事件,但又进行了事件拦截,没有传递给parent ViewGroup ,由于在onTouchEvent事件没有对enable状态判断,
所以事件仍然在onTouchEvent rerurn true。解决重写EditText的onTouchEvent 增加isEnable判断即可:
public class EditTextTouch extends EditText { public EditTextTouch(Context context) { this(context, null); } public EditTextTouch(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { return isEnabled() && super.onTouchEvent(event); } }
EditText代码实现动态设置输入类型:
setInputType(InputType.TYPE_CLASS_PHONE);
setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME);
自定义类型 通过setKeyListener()
setKeyListener(new MyNumberType());
private class MyNumberType extends NumberKeyListener { @NonNull @Override protected char[] getAcceptedChars() {//限制内容 char[] numberChars={'1','2','3','4','5','6','7','8','9','.','0',}; return numberChars; } @Override public int getInputType() { return android.text.InputType.TYPE_CLASS_PHONE; } }
限定输入字符
xml中我们可以使用digits属性可以实现字符的限定,代码中EditText提供setKeyListener(KeyListener )和setFilters(InputFilter[])两个方法
setFilters
如限制输入输入字数为8
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(8)});
只能输入8位大写字母
editText.setFilters(new InputFilter[]{new InputFilter.AllCaps(),new InputFilter.LengthFilter(8)});
InputFilter switchFilter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
return source.toString().toUpperCase();
}
};
editText.setFilters(new InputFilter[]{switchFilter,new InputFilter.LengthFilter(16)});
setKeyListener方式
InputFilter提供了字符过滤,KeyListener提供了对输入键盘按键的监听。
DigitsKeyListener、NumberKeyListener是我们经常使用的,DigitsKeyListener继承了NumberKeyListener,NumberKeyListener实现了InputFilter,
所以我们在使用InputFilter的时候发现也可以设置DigitsKeyListener和NumberKeyListener
//https://blog.csdn.net/xuwb123xuwb/article/details/71081174
//https://www.jianshu.com/p/bd4273c12e5b
textview 设置图片两种方式:
TextView textView=null; 1, int flagResId = getResources().getIdentifier("icon", "drawable", getPackageName()); textView.setCompoundDrawablesWithIntrinsicBounds(flagResId, 0, 0, 0); 2, Drawable drawable = mContext.getResources().getDrawable(R.drawable.shop_arrow_down); drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight()); textView.setCompoundDrawables(null, null, drawable, null);
TextView控件的背景透明度和字体透明度
方式1, tv.setBackgroundColor(Color.argb(255, 0, 255, 0)); //背景透明度 tv.setTextColor(Color.argb(255, 0, 255, 0)); //文字透明度 方式2, tv.setTextColor(0xffff00ff);
0xffff00ff是int类型的数据,分组一下0x|ff|ff00ff,0x是代表颜色整数的标记,ff是表示透明度,ff00ff表示颜色,注意:这里ffff00ff必须是8个的颜色表示
原理,把透明度转换为色值。就是根据透明度转换为色值,放在前两位
透明度转换可以参照下表: 透明度 对应十六进制 100% ff 90% e6 85% d9 80% cc 70% b3 60% 99 50% 80 40% 66 30% 4d 20% 33 15% 26 10% 1a 5% 0d 0% 00
代码设置EditText输入限制:
public void setNumInputType(String str){ //digits="0123456789" 只数字 //"0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 字母+数字 etInput.setKeyListener(DigitsKeyListener.getInstance(str)); } // etInput.setInputType(InputType.TYPE_CLASS_NUMBER);//数字键盘 // InputType.TYPE_TEXT_FLAG_MULTI_LINE);//设置输入类型和键盘为英文 // etInput.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
one textView different text style
String s= "Hello Everyone"; SpannableString ss1= new SpannableString(s); ss1.setSpan(new RelativeSizeSpan(2f), 0,5, 0); // set size ss1.setSpan(new ForegroundColorSpan(Color.RED), 0, 5, 0);// set color TextView tv= (TextView) findViewById(R.id.textview); tv.setText(ss1);
textView.setText(Html.fromHtml("<b>myLogin</b> <i>logout</i>"));SpannableString styledString = new SpannableString("myLogin logout"); styledString.setSpan(new StyleSpan(Typeface.BOLD), 0, 7, 0); styledString.setSpan(new StyleSpan(Typeface.ITALIC), 8, 14, 0); tv.setText(styledString);
计算字体宽度:
public static float GetTextWidth(String text, float Size) {
TextPaint FontPaint = new TextPaint();
FontPaint.setTextSize(Size);
return FontPaint.measureText(text);
}
// 计算文本,行数,高度
FontMetrics fm = mTextView.getPaint().getFontMetrics();
mFontHeight = (int) (Math.ceil(fm.descent - fm.top) + 2);// 获得每行高度
mPageLineNum = (int) (mTextHeight / mFontHeight);// 获得行数
//TextView 分页设置相关
getLineBounds(int line, Rect bounds) // 得到指定行的边界
只要从第一行开始一行一行往下看, 直到找到超出边界的那一行, 就能知道这个 TextView 能显示多少行了.
或者用 getHeight() / getLineHeight() 也能获取 TextView 的最大显示行数
getLineForVertical(int vertical) // 根据纵坐标得到对应的行号
getLineEnd(int line) // 返回指定行中最后一个字在整个字符串中的位置
一个TextView设置多种颜色文字
Html.fromHtml(String.format(formate, getColorText(params, color)));
public class ReadView extends TextView { // 构造函数略... @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); resize(); } /** * 去除当前页无法显示的字 * @return 去掉的字数 */ public int resize() { CharSequence oldContent = getText(); CharSequence newContent = oldContent.subSequence(0, getCharNum()); setText(newContent); return oldContent.length() - newContent.length(); } /** * 获取当前页总字数 */ public int getCharNum() { return getLayout().getLineEnd(getLineNum()); } /** * 获取当前页总行数 */ public int getLineNum() { Layout layout = getLayout(); int topOfLastLine = getHeight() - getPaddingTop() - getPaddingBottom() - getLineHeight(); return layout.getLineForVertical(topOfLastLine); } }
//TextView设置完setMaxLines后,通过TextView.getHeight方法获取的是当前行数的高度,而非文字完全显示的高度
//实际获取高度方法
/** * * @param pTextView * @return */ private int getTextViewHeight(TextView pTextView) { Layout layout = pTextView.getLayout(); int desired = layout.getLineTop(pTextView.getLineCount()); int padding = pTextView.getCompoundPaddingTop() + pTextView.getCompoundPaddingBottom(); return desired + padding; }
//自定义View绘制文本时,格式化文本内容StaticLayout实现:
public void onDraw(Canvas canvas){ super.onDraw(canvas); TextPaint tp = new TextPaint(); tp.setColor(Color.BLUE); tp.setStyle(Style.FILL); tp.setTextSize(50); String message = "paint,draw paint指用颜色画,如油画颜料、水彩或者水墨画,而draw 通常指用铅笔、钢笔或者粉笔画,后者一般并不涂上颜料。两动词的相应名词分别为p"; StaticLayout myStaticLayout = new StaticLayout(message, tp, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); myStaticLayout.draw(canvas); canvas.restore(); }
自定义view绘制文本计算文本宽度高度:
private Rect mBounds = new Rect(); String text = String.valueOf(mCount); mPaint.getTextBounds(text, 0, text.length(), mBounds); float textWidth = mBounds.width(); float textHeight = mBounds.height(); canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2 + textHeight / 2, mPaint);
文本分割处理
/** * 自动分割文本 * @param content 需要分割的文本 * @param p 画笔,用来根据字体测量文本的宽度 * @param width 最大的可显示像素(一般为控件的宽度) * @return 一个字符串数组,保存每行的文本 */ public static String[] autoSplitText(String content, Paint p, int width) { float textWidth = p.measureText(content); if(textWidth <= width) { return new String[]{content}; } int length = content.length(); int start = 0, end = 1, i = 0; int lines = (int) Math.ceil(textWidth / width); //计算行数 String[] lineTexts = new String[lines]; while(start < length) { if(p.measureText(content, start, end) > width) { //文本宽度超出控件宽度时 lineTexts[i++] = content.substring(start, end);//(String) content.subSequence(start, end); start = end; } if(end == length) { //不足一行的文本 lineTexts[i] = content.substring(start, end);//(String) content.subSequence(start, end); break; } end += 1; } return lineTexts; }
TextView字体间距
1、android:lineSpacingExtra
设置行间距,如”3dp”。
2、android:lineSpacingMultiplier
设置行间距的倍数,如”1.2″。
设置texview 垂直滚动条
android:focusable="true"
android:focusableInTouchMode="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollbars="vertical"
android:singleLine="false"
设置textview 文字水平自动滚动(跑马灯效果)
<com.example.playpic.MyTextView android:id="@+id/myTv" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textColor="#000000" android:focusable="true" android:focusableInTouchMode="true" android:scrollHorizontally="true" android:ellipsize="marquee" android:marqueeRepeatLimit="marquee_forever" android:singleLine="true" />
布局文件需添加属性:android:addStatesFromChildren="true"
修改的textview
public class MyTextView extends TextView { public MyTextView(Context context) { super(context); } public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); } public MyTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override public boolean isFocused() { return true; } } setContentView(R.layout.scrollview1); MyTextView tv=(MyTextView)findViewById(R.id.myTv); tv.setText(str); tv.setMovementMethod(ScrollingMovementMethod.getInstance());
android 动态设置TextView值,例:金额增加
public static void autoIncrement(final TextView target, final float start, final float end, long duration) { ValueAnimator animator = ValueAnimator.ofFloat(start, end); animator.addUpdateListener(new AnimatorUpdateListener() { private FloatEvaluator evalutor = new FloatEvaluator(); private DecimalFormat format = new DecimalFormat("####0.0#"); @Override public void onAnimationUpdate(ValueAnimator animation) { float fraction = animation.getAnimatedFraction(); float currentValue = evalutor.evaluate(fraction, start, end); target.setText(format.format(currentValue)); } }); animator.setDuration(duration); animator.start(); }
Textview 设置maxLines>1时,超出部分内容没...省略号解决方法
解决方案:1,自定义实现,2,通过post(Runable r)即在Textview设置文字后显示完计算处理
class OmitTextViewDeal implements Runnable{ TextView tv; String txt; public GoodsAttributeTextViewDeal(){ } @Override public void run() { float txtLen=tv.getPaint().measureText(txt); int tvLen=tv.getWidth(); int lines=Math.round(txtLen/tvLen+0.9f); if(lines>2){ String[] splitContent= UtilsView.autoSplitText(txt,tv.getPaint(),tvLen); String ts=splitContent[1].substring(0,splitContent[1].length()-5); String showTxt=splitContent[0]+ts+"..."; tv.setText(showTxt); } } } public static String[] autoSplitText(String content, Paint p, int width) { float textWidth = p.measureText(content); if(textWidth <= width) { return new String[]{content}; } int length = content.length(); int start = 0, end = 1, i = 0; int lines = (int) Math.ceil(textWidth / width); //计算行数 String[] lineTexts = new String[lines]; while(start < length) { if(p.measureText(content, start, end) > width) { //文本宽度超出控件宽度时 lineTexts[i++] = content.substring(start, end);//(String) content.subSequence(start, end); start = end; } if(end == length) { //不足一行的文本 lineTexts[i] = content.substring(start, end);//(String) content.subSequence(start, end); break; } end += 1; } return lineTexts; }
使用:
tv_attr.setText(txtAttr); OmitTextViewDeal attrTvDeal=new OmitTextViewDeal(); attrTvDeal.tv=tv_attr; attrTvDeal.txt=txtAttr; holder.tv_attr.post(attrTvDeal);
文本分割处理
/** * 在文字信息绘制前对文本信息进行文字分割,文字间距,文字位置计算处理 * @param text */ private void initDrawText(String text){ if(texts==null){ texts=getTexts(text); } if(tposy==null){ tposy=getTextLinePosy(); } if(stepBack==null){ stepBack=new Float[tposy.length]; int i=0; float interval=0.0f; FontMetrics fm = textPaint.getFontMetrics(); float baseline = fm.descent - fm.ascent; while(i<stepBack.length){ stepBack[i]=interval; interval-=baseline; i++; } } if(step==null){ step=stepBack.clone(); } } /** * 获取分割后的文本信息 * @param text * @return */ private String[] getTexts(String text){ if(text.contains(" ")){ List<String> totalList=new ArrayList<String>(10); String[] str=text.split(" "); int len=str.length; for(int i=0;i<len;i++){ String[] ss=autoSplit(str[i], textPaint, getWidth()/3*2); for(String s:ss){ totalList.add(s); } } if(texts==null) texts=(String[]) totalList.toArray(new String[0]); } else texts=autoSplit(text, textPaint, getWidth()/3*2); return texts; } /** * 获取每行文本的纵坐标信息 * @return */ private Float[] getTextLinePosy(){ FontMetrics fm = textPaint.getFontMetrics(); float baseline = fm.descent - fm.ascent; float y = posy+baseline; //由于系统基于字体的底部来绘制文本,所有需要加上字体的高度 int len=texts.length; Float[] groups=new Float[len]; for(int i=0;i<len;i++) { groups[i]=y; y =y+ baseline + fm.leading; //添加字体行间距 } return groups; } /** * 自动分割文本 * @param content 需要分割的文本 * @param p 画笔,用来根据字体测量文本的宽度 * @param width 最大的可显示像素(一般为控件的宽度) * @return 一个字符串数组,保存每行的文本 */ private String[] autoSplit(String content, Paint p, float width) { float textWidth = p.measureText(content); if(textWidth <= width) { return new String[]{content}; } int length = content.length(); int start = 0, end = 1, i = 0; int lines = (int) Math.ceil(textWidth / width); //计算行数 String[] lineTexts = new String[lines]; while(start < length) { if(p.measureText(content, start, end) > width) { //文本宽度超出控件宽度时 lineTexts[i++] = content.substring(start, end);//(String) content.subSequence(start, end); start = end; } if(end == length) { //不足一行的文本 lineTexts[i] = content.substring(start, end);//(String) content.subSequence(start, end); break; } end += 1; } return lineTexts; }
大文本分页显示处理:
package sharedcode.turboeditor.texteditor; import android.content.Context; import java.util.LinkedList; import java.util.List; import sharedcode.turboeditor.preferences.PreferenceHelper; public class PageSystem { private List<String> pages; private int[] startingLines; private int currentPage = 0; private PageSystemInterface pageSystemInterface; public PageSystem(Context context, PageSystemInterface pageSystemInterface, String text) { final int charForPage = 20000; final int firstPageChars = 50000; this.pageSystemInterface = pageSystemInterface; pages = new LinkedList<>(); int i = 0; int to; int nextIndexOfReturn; final int textLength = text.length(); boolean pageSystemEnabled = PreferenceHelper.getSplitText(context); if (pageSystemEnabled) { while (i < textLength) { // first page is longer to = i + (i == 0 ? firstPageChars : charForPage); nextIndexOfReturn = text.indexOf(" ", to); if (nextIndexOfReturn > to) to = nextIndexOfReturn; if (to > text.length()) to = text.length(); pages.add(text.substring(i, to)); i = to + 1; } if (i == 0) pages.add(""); } else { pages.add(text); } startingLines = new int[pages.size()]; setStartingLines(); } public int getStartingLine() { return startingLines[currentPage]; } public String getCurrentPageText() { return pages.get(currentPage); } public String getTextOfNextPages(boolean includeCurrent, int nOfPages) { StringBuilder stringBuilder = new StringBuilder(); int i; for (i = includeCurrent ? 0 : 1; i < nOfPages; i++) { if (pages.size() > (currentPage + i)) { stringBuilder.append(pages.get(currentPage + 1)); } } return stringBuilder.toString(); } public void savePage(String currentText) { pages.set(currentPage, currentText); } public void nextPage() { if (!canReadNextPage()) return; goToPage(currentPage + 1); } public void prevPage() { if (!canReadPrevPage()) return; goToPage(currentPage - 1); } public void goToPage(int page) { if (page >= pages.size()) page = pages.size() - 1; if (page < 0) page = 0; boolean shouldUpdateLines = page > currentPage && canReadNextPage(); if (shouldUpdateLines) { String text = getCurrentPageText(); int nOfNewLineNow = (text.length() - text.replace(" ", "").length()) + 1; // normally the last line is not counted so we have to add 1 int nOfNewLineBefore = startingLines[currentPage + 1] - startingLines[currentPage]; int difference = nOfNewLineNow - nOfNewLineBefore; updateStartingLines(currentPage + 1, difference); } currentPage = page; pageSystemInterface.onPageChanged(page); } public void setStartingLines() { int i; int startingLine; int nOfNewLines; String text; startingLines[0] = 0; for (i = 1; i < pages.size(); i++) { text = pages.get(i - 1); nOfNewLines = text.length() - text.replace(" ", "").length() + 1; startingLine = startingLines[i - 1] + nOfNewLines; startingLines[i] = startingLine; } } public void updateStartingLines(int fromPage, int difference) { if (difference == 0) return; int i; if (fromPage < 1) fromPage = 1; for (i = fromPage; i < pages.size(); i++) { startingLines[i] += difference; } } public int getMaxPage() { return pages.size() - 1; } public int getCurrentPage() { return currentPage; } public String getAllText(String currentPageText) { pages.set(currentPage, currentPageText); int i; StringBuilder allText = new StringBuilder(); for (i = 0; i < pages.size(); i++) { allText.append(pages.get(i)); if(i < pages.size() - 1) allText.append(" "); } return allText.toString(); } public boolean canReadNextPage() { return currentPage < pages.size() - 1; } public boolean canReadPrevPage() { return currentPage >= 1; } public interface PageSystemInterface { void onPageChanged(int page); } }
use page:
InputStream inputStream = getContentResolver().openInputStream(uri); if(inputStream != null) { buffer = new BufferedReader(new InputStreamReader(inputStream, encoding)); } if (buffer != null) { while((line = buffer.readLine()) != null) { stringBuilder.append(line); stringBuilder.append(" "); } buffer.close(); fileText = stringBuilder.toString(); } pageSystem = new PageSystem(MainActivity.this, MainActivity.this, fileText); pageSystem.goToPage(value); mEditor.setText(pageSystem.getCurrentPageText());