做了2年多的Android开发,感觉自己一直没有什么进步,学了很多东西,都是东一块,西一块,不成系统,全是零零散散的知识点,而且很多学过就没有使用过了,做了无用功。所以希望以写分享的方式来记录下自己的学习。这里先 flag,我要写10篇关于自定义控的文章,边学习,边记录,在6月30号前完成。现在开始第一篇的内容。
1.需求
昨天在群里有个群友问,这样的一个需求,如图所示,左右两个Textview ,红色的显示时间,文字长度固定;绿色的文字长度不固定,如果绿色文字少则红绿相邻,一排显示,如果绿色文字多,则绿色多排显示多排,红色显示在父控件右端不被绿色的挤出去。
2.思考
1.开始想法是这不是很简单,一个LineLayout 里放两个textview ,绿色的宽度自适应,红色的设置固定长度,不就行了。事实证明,想法too young
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="海上生明月海上生明月海上生明月海上生明月海上生明月海上生明月"
android:background="#00ff00"
/>
<TextView
android:layout_width="80dp"
android:layout_height="wrap_content"
android:text="花开彼岸天"
android:background="#ff0000"
/>
</LinearLayout>
结果是:
绿色的把红色的挤没了,这就尴尬了,我想具体原因肯定和LineLayout 的 onLayout()有关系,有时间一定好好研究一下
2.本少想了想,还是很简单啊,在绿色的textview上加一个maxWidth貌似可以解决
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="200dp"
android:text="海上生明月海上生明月海上生明月海上生明月海上生明月海上生明月海上生明月"
android:background="#00ff00"
/>
<TextView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="花开彼岸天"
android:background="#ff0000"
/>
</LinearLayout>
结果是:
结果是可以的,但是这样不好处理适配啊,maxWidth设多长才合适呢,如果特意去做适配,也是可以的,但是本宝宝不喜欢,我不喜欢有什么用,想了想之前写过的标签流,貌似可以自己写一个控件去处理
3.站撸
写一个父控件 ,包含两个textview 。先测量出父控件的宽度,两个子控件的宽度,重点在于onLayout里,如果 tv1和tv2的宽度纸盒小于父控件宽度,则一列依次显示;如果大于父控件宽度,则改变tv1的形状,宽为tv1的最大宽度(父控件宽度-tv2的宽度),高为 原宽度*(原宽度/最大宽度),然后依次显示
public class MyView extends ViewGroup {
TextView tv1;
TextView tv2;
final int defsize=200;
public MyView(Context context) {
super(context);
initView();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int tv1w=tv1.getMeasuredWidth();
int tv1h=tv1.getMeasuredHeight();
int tv2w=tv2.getMeasuredWidth();
int tv2h=tv2.getMeasuredHeight();
int vieww=getMeasuredWidth();
int tv1MaxW=vieww-tv2w;
Log.i("onLayout","tv1w:"+tv1w);
Log.i("onLayout","tv1h:"+tv1h);
Log.i("onLayout","tv2w:"+tv2w);
Log.i("onLayout","tv2h:"+tv2h);
Log.i("onLayout","vieww:"+vieww);
Log.i("onLayout","max:"+tv1MaxW);
if(tv1w+tv2w<vieww){
tv1.layout(0,0,tv1w,tv1h);
tv2.layout(tv1w,0,tv1w+tv2w,tv2h);
}else {
tv1.setWidth(tv1MaxW);
tv1.setHeight((tv1w/tv1MaxW+1)*tv1h);
tv1.layout(0,0,tv1MaxW,(tv1w/tv1MaxW+1)*tv1h);
tv2.layout(tv1MaxW,0,tv1MaxW+tv2w,tv2h);
}
}
private void initView() {
tv1=new TextView(getContext());
tv1.setText("海上生明月");
tv1.setBackgroundColor(Color.BLUE);
tv2=new TextView(getContext());
tv2.setText("天涯共此时");
tv2.setBackgroundColor(Color.GREEN);
setBackgroundColor(Color.RED);
addView(tv1);
addView(tv2);
}
public void setText(String text1, String text2){
tv1.setText(text1);
tv2.setText(text2);
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = myOnMeasure(widthMeasureSpec,defsize);
int height = myOnMeasure(heightMeasureSpec,defsize);
Log.i("onMeasure",width+"");
Log.i("onMeasure",height+"");
setMeasuredDimension(width,height);
tv1.measure(width,height);
tv2.measure(width,height);
}
public int myOnMeasure(int measureSpec,int defsize) {
int mode = View.MeasureSpec.getMode(measureSpec);
int size = View.MeasureSpec.getSize(measureSpec);
int realSize;
if(mode== View.MeasureSpec.EXACTLY){
realSize=size;
}else if(mode== View.MeasureSpec.AT_MOST){
if(size<1){
realSize=defsize;
}else {
realSize=Math.min(size,defsize);
}
}else {
realSize=defsize;
}
return realSize;
}
}
4.总结
写的时候发现,好像是不是内容太low了,我都不敢给同事和我女朋友看(做ui的,上班旁边就有程序员),第一次正经写分享,第一次用markdown,大家多包涵,谢谢.