android TextView相關屬性及文本處理


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());
相關文章
相關標籤/搜索