在android中用的最多的就是TextView,如果我們要獲取TextView在父佈局中的位置來如何處理呢,主要原理還是利用
getLeft(),getRight(),getTop(),getBottom(),getX,getY來計算,這裏就是對這幾個方法的使用說明
我們做一個實驗,畫了一個寬爲300 高100的矩形框,這時左邊有,上邊也有一個高有100的矩形框
前提條件
父佈局:相距屏幕左邊的邊距是40
左邊:一個寬爲100的矩形框
上邊:一個高爲100的矩形框
這時我們點擊獲取這個300*100圖片的getLeft(),getRight(),getTop(),getBottom(),getX,getY,獲取的結果圖片如下
從圖中我們可以看出來,getLeft和getx都是相對父佈局的,但不包括父佈局的marginleft,gettop和gety也是相對父佈局的,這裏最不同的是getRight和getBottom,getRight是控件最右邊相對於父控件左邊的距離,getBottom是控件最下面相對父控件頂部的距離。
getleft | 100 | 左100 |
getright | 400 | 寬300+左100 |
gettop | 100 | 上100 |
getbottom | 200 | 高100+上100 |
getx | 100 | 左100 |
gety | 100 | 上100 |
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp">
<TextView
android:id="@+id/left"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_below="@+id/top"
android:text="左100" />
<com.sinping.arouter.myandroid.component.SimpleTextView
android:id="@+id/simpleTextView_20"
android:layout_width="150dp"
android:layout_height="50dp"
android:gravity="center"
android:layout_toRightOf="@+id/left"
android:layout_below="@+id/top"
android:text="寬300高100" />
<TextView
android:id="@+id/top"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="上100" />
<TextView
android:id="@+id/left_right_top_bottom_20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/simpleTextView_20"
android:textSize="20sp"/>
</RelativeLayout>
</LinearLayout>
simpleTextView_20.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
left_right_top_bottom_20.setText(
" left" + simpleTextView_20.getLeft()
+ "\n right" + simpleTextView_20.getRight()
+ "\n top" + simpleTextView_20.getTop()
+ "\n bottom" + simpleTextView_20.getBottom()
+"\n x" + simpleTextView_20.getX()
+"\n y" + simpleTextView_20.getY()
);
}
});
到這裏只是計算了控件的幾個屬性,還是沒有介紹TextView是如何計算文字相對父控件的位置的,下面我們專一來講解這個,這些內容也是參考了magic的源碼,我這裏只是做了分解。
這裏先要介紹這個方法getTextBound,這個方法是計算文字的寬度的,原理把文字放入一個矩形內來計算文字的寬度,這個方法以後再詳細介紹,得到的結果如下圖:
在這裏計算寬度用到了getTextBound方法,計算高度用到了getPaint().getFontMetrics()方法,有了這些方法的支撐,我們就可以得到文字的位置了,代碼如下
public class SimpleTextView extends AppCompatTextView {
public SimpleTextView(Context context) {
super(context);
}
public SimpleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SimpleTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public int getContentLeft(){
String longestString = "";
Rect rect =new Rect();
longestString=getText().toString();
getPaint().getTextBounds(longestString,0,longestString.length(),rect);
//計算文本的left
return getLeft()+getWidth()/2-rect.width()/2;
}
public int getContentRight(){
String longestString = "";
Rect rect =new Rect();
longestString=getText().toString();
getPaint().getTextBounds(longestString,0,longestString.length(),rect);
//計算文本的right
return getLeft()+getWidth()/2+rect.width()/2;
}
public float getContentTop(){
Paint.FontMetrics metrics = getPaint().getFontMetrics();
float contentHeight = metrics.bottom - metrics.top;
//計算文本的top
return getTop()+ getHeight()/2-contentHeight/2;
}
public float getContentBottom(){
Paint.FontMetrics metrics = getPaint().getFontMetrics();
float contentHeight = metrics.bottom - metrics.top;
//計算文本的bottom
return getTop()+getHeight()/2+contentHeight/2;
}
}