Edittext響應onclick,因爲click事件被onTouchEvent攔截,因此經過設置touch事件監聽處理java
// 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狀態判斷,android
因此事件仍然在onTouchEvent rerurn true。解決重寫EditText的onTouchEvent 增長isEnable判斷便可:git
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代碼實現動態設置輸入類型:canvas
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和NumberKeyListenerapp
//https://blog.csdn.net/xuwb123xuwb/article/details/71081174
//https://www.jianshu.com/p/bd4273c12e5b
ide
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個的顏色表示
原理,把透明度轉換爲色值。就是根據透明度轉換爲色值,放在前兩位
post
透明度轉換能夠參照下表: 透明度 對應十六進制 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字體間距
一、android:lineSpacingExtra
設置行間距,如」3dp」。
二、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("\n")){ List<String> totalList=new ArrayList<String>(10); String[] str=text.split("\n"); 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("\n", 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("\n", "").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("\n", "").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("\n"); } 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("\n"); } buffer.close(); fileText = stringBuilder.toString(); } pageSystem = new PageSystem(MainActivity.this, MainActivity.this, fileText); pageSystem.goToPage(value); mEditor.setText(pageSystem.getCurrentPageText());