(一)問題
怎樣實現帶有橫欄的EditText(像記事本的編輯界面那樣)?
(二)初步思路
1.通過修改EditText背景來實現(系統背景是一個框形圖片,內部透明,替換為一個帶有橫欄的圖片即可)
2.通過重繪EditText來實現(自定義組件,自己畫線)
3.用ListView實現(ListView本身就會顯示橫線)
(三)深入分析
1.EditText顯示多行文本時會自動拉伸背景,若要保證邊框不會失真,需要用9patch圖片來做背景,或許能夠實現
2.毫無疑問,自定義EditText一定可以實現橫線的顯示(沒有槍炮就自己造...),但是自定義組件比較麻煩(需要重寫很多東西),能用其他方法解決當然更好
3.ListView用來顯示多行文本可能比較好(將Text分割為等長String存入Array,作為ListView的Adapter),但是若要編輯文本則明顯不合適
(四)初步實踐
1.通過多次測試發現改變EditText的背景圖能夠顯示橫欄,但僅限於SingLine的文本,因為輸入多行文本時背景圖會向下拉伸(橫線沒了...)。所以測試結果是:用自定義背景圖只能顯示帶下划線的單行文本,方案一失敗!但是在此過程中學到了9patch圖片的用處,算是一點小收獲。
2.通過重寫EditText的onDraw方法來繪制需要的橫線,如何確定橫線的位置成為核心問題(本質是獲取一組起點坐標和一組對應的終點坐標),此方法在下面展開詳述
3.ListView的缺點在上面已經說過了,但是經過對方案一的嘗試,我們很容易發現方案一和方案三恰好互補(把方案一得到的EditText作為ListView的Item),此時應該為EditText自定義selector,設置focus時不發光即可。測試結果是:單行EditText負責按行顯示文本,ListView負責畫線,方案一組合方案三可行。
(五)自定義EditText實現橫欄的顯示
[自定義myEditText類]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
package
com.ayqy.app_test;
import
android.content.Context;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
import
android.widget.EditText;
public
class
myEditText
extends
EditText{
private
int
lineColor;
//橫線顏色
private
float
lineWidth;
//橫線寬度
public
myEditText(Context context) {
super
(context);
//設置默認顏色和橫線寬度
lineColor = Color.BLUE;
//默認藍色線
lineWidth = 2f;
//寬度為2
}
public
myEditText(Context context,
int
color,
float
width) {
super
(context);
//設置顏色和橫線寬度
this
.lineColor = color;
this
.lineWidth = width;
}
@Override
protected
void
onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super
.onDraw(canvas);
//創建畫筆
Paint mPaint =
new
Paint();
mPaint.setStrokeWidth(lineWidth);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(lineColor);
//獲取參數
int
w =
this
.getWidth();
//獲取控件寬度
int
h =
this
.getHeight();
//獲取控件高度
int
padB =
this
.getPaddingBottom();
//獲取底部留白
int
padL =
this
.getPaddingLeft();
//獲取左邊留白
int
padR =
this
.getPaddingRight();
//獲取右邊留白
float
size =
this
.getTextSize() *
7
/
6
;
//獲取橫欄間距(TextSize的默認值為18)
/*設置size的值是一個核心問題,size的值要適應不同的字體大小(不同大小字體的行距也不同)
*經過多次嘗試發現以字體大小的7/6倍作為橫欄間距最合適
* */
int
lines = (
int
)(h / size);
//獲取行數
//從下向上畫線
for
(
int
i =
0
;i < lines;i++)
canvas.drawLine(padL
//startX
,
this
.getHeight() - padB - size * i
//startY
,
this
.getWidth() - padR
//endX
,
this
.getHeight() - padB - size * i
//endY
, mPaint);
}
public
int
getLineColor() {
return
lineColor;
}
public
void
setLineColor(
int
color) {
this
.lineColor = color;
}
public
float
getLineWidth() {
return
lineWidth;
}
public
void
setLineWidth(
float
width) {
this
.lineWidth = width;
}
}
|
[布局文件]
[測試類]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package
com.ayqy.app_test;
import
android.app.Activity;
import
android.os.Bundle;
import
android.view.Menu;
import
android.widget.LinearLayout;
public
class
MainActivity
extends
Activity {
LinearLayout root;
//聲明根布局
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
root = (LinearLayout) findViewById(R.id.root);
//獲取根布局
//創建自定義EditText控件對象
myEditText txt =
new
myEditText(
this
);
//設置多行文本
txt.setText(
"這是一個很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的測試內容"
);
//用來測試是否能夠適應不同大小的字體
//txt.setTextSize(48);
//txt.setTextSize(24);
root.addView(txt);
//添加控件
}
@Override
public
boolean
onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return
true
;
}
}
|
[P.S.以上源碼本機測試無誤,若在測試中發現任何問題請在下方留言]
(六)測試結果圖片
(七)總結
嘗試是解決問題的最好方法,即便最終問題得不到解決,其間的思考也是一種鍛煉
(八)BUG修正
此版本存在BUG,詳情及修正方法見 http://www.cnblogs.com/ayqy/p/3600289.html