View,viewgroup,viewstub总结
- package com.example.xiutest;
- import java.io.File;
- import java.util.ArrayList;
- import java.util.List;
- publicclassMainActivityextendsActivityimplementsOnClickListener,OnTouchListener{
- privateContext ctx;
- privateBoolean isFrist=true;
- privateImageView dargtool;
- privateint lastX;
- privateint lastY;
- privateint startTop;
- privateint startBottom;
- privateint startLeft;
- privateint startRight;
- @Override
- protectedvoid onCreate(Bundle savedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- ctx =this;
- dargtool=(ImageView)findViewById(R.id.dargtool);
- dargtool.setOnTouchListener(this);
- }
- @Override
- publicboolean onTouch(View v,MotionEvent event){
- switch(event.getAction()){
- caseMotionEvent.ACTION_MOVE:
- int dx =(int)event.getRawX()- lastX;
- int dy =(int)event.getRawY()- lastY;
- int left = v.getLeft()+ dx;
- int top = v.getTop()+ dy;
- int right = v.getRight()+ dx;
- int bottom = v.getBottom()+ dy;
- if(left <0){
- left =0;
- right = left + v.getWidth();
- }
- if(right >720){
- right =720;
- left = right - v.getWidth();
- }
- if(top <0){
- top =0;
- bottom = top + v.getHeight();
- }
- if(bottom >600){
- bottom =600;
- top = bottom - v.getHeight();
- mHandler.sendEmptyMessage(3);
- }
- v.layout(left, top, right, bottom);
- lastX =(int) event.getRawX();
- lastY =(int) event.getRawY();
- break;
- caseMotionEvent.ACTION_DOWN:
- if(isFrist){
- startTop=dargtool.getTop();
- startBottom=dargtool.getBottom();
- startLeft=dargtool.getLeft();
- startRight=dargtool.getRight();
- isFrist=false;
- }
- lastX =(int) event.getRawX();
- lastY =(int) event.getRawY();
- break;
- caseMotionEvent.ACTION_UP:
- v.layout(startLeft, startTop, startRight, startBottom);
- break;
- default:
- break;
- }
- returntrue;
- }
- }
可拖动的View控件
int dy =(int)event.getRawY()- lastY;获取事件的绝对位置的变化, 转移给相对于父控件的相对位置View聚焦
- <TextView
- android:id="@+id/mine_nickname"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:ellipsize="marquee"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:gravity="center"
- android:marqueeRepeatLimit="marquee_forever"
- android:scrollHorizontally="true"
- android:singleLine="true"
- android:text=""
- android:textColor="@color/hovn_index_room_name"
- android:textSize="@dimen/mine_info_name_size"/>
自定义的viewgroup允许添加子view
- //设置是否能够调用自定义的布局,false是可以
- setWillNotDraw(false);
- //优先其子类控件而获取到焦点
- setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
View.requestLayout()和invalidate
View的略缩图
- privateBitmap getViewBitmap(View view ){
- view.setDrawingCacheEnabled(true);
- Bitmap bitmap =null;
- try{
- if(null!= view.getDrawingCache()){
- bitmap =Bitmap.createScaledBitmap( view.getDrawingCache(),256,192,false);
- }else{
- Bitmap bitmapTmp =((BitmapDrawable)( getResources().getDrawable( R.drawable.syncompdetailcontent_background ))).getBitmap();
- }
- }catch(OutOfMemoryError e ){
- e.printStackTrace();
- }finally{
- view.setDrawingCacheEnabled(false);
- view.destroyDrawingCache();
- }
- return bitmap;
- }
- /**
- * 把View绘制到Bitmap上
- * @param view 需要绘制的View
- * @param width 该View的宽度
- * @param height 该View的高度
- * @return 返回Bitmap对象
- * add by csj 13-11-6
- */
- publicBitmap getViewBitmap(View comBitmap,int width,int height){
- Bitmap bitmap = null;
- if(comBitmap != null){
- comBitmap.clearFocus();
- comBitmap.setPressed(false);
- boolean willNotCache = comBitmap.willNotCacheDrawing();
- comBitmap.setWillNotCacheDrawing(false);
- // Reset the drawing cache background color to fully transparent
- // for the duration of this operation
- int color = comBitmap.getDrawingCacheBackgroundColor();
- comBitmap.setDrawingCacheBackgroundColor(0);
- float alpha = comBitmap.getAlpha();
- comBitmap.setAlpha(1.0f);
- if(color !=0){
- comBitmap.destroyDrawingCache();
- }
- int widthSpec =View.MeasureSpec.makeMeasureSpec(width,View.MeasureSpec.EXACTLY);
- int heightSpec =View.MeasureSpec.makeMeasureSpec(height,View.MeasureSpec.EXACTLY);
- comBitmap.measure(widthSpec, heightSpec);
- comBitmap.layout(0,0, width, height);
- comBitmap.buildDrawingCache();
- Bitmap cacheBitmap = comBitmap.getDrawingCache();
- if(cacheBitmap == null){
- Log.e("view.ProcessImageToBlur","failed getViewBitmap("+ comBitmap +")",
- newRuntimeException());
- return null;
- }
- bitmap =Bitmap.createBitmap(cacheBitmap);
- // Restore the view
- comBitmap.setAlpha(alpha);
- comBitmap.destroyDrawingCache();
- comBitmap.setWillNotCacheDrawing(willNotCache);
- comBitmap.setDrawingCacheBackgroundColor(color);
- }
- return bitmap;
- }
- privateBitmap getViewBitmap(View v){
- v.clearFocus();
- v.setPressed(false);
- boolean willNotCache = v.willNotCacheDrawing();
- v.setWillNotCacheDrawing(false);
- // Reset the drawing cache background color to fully transparent
- // for the duration of this operation
- int color = v.getDrawingCacheBackgroundColor();
- v.setDrawingCacheBackgroundColor(0);
- if(color !=0){
- v.destroyDrawingCache();
- }
- v.buildDrawingCache();
- Bitmap cacheBitmap = v.getDrawingCache();
- if(cacheBitmap == null){
- Log.e("Folder","failed getViewBitmap("+ v +")",newRuntimeException());
- return null;
- }
- Bitmap bitmap =Bitmap.createBitmap(cacheBitmap);
- // Restore the view
- v.destroyDrawingCache();
- v.setWillNotCacheDrawing(willNotCache);
- v.setDrawingCacheBackgroundColor(color);
- return bitmap;
- }
- View view = mLauncher.getDragLayer();
- view.setDrawingCacheEnabled(true);
- Bitmap bitmap = view.getDrawingCache();
ViewGroup提高绘制性能
- publicvoid setChildrenDrawingCacheEnabled(boolean enabled){
- final int count = getChildCount();
- for(int i =0; i < count; i++){
- final View view = getChildAt(i);
- view.setDrawingCacheEnabled(true);
- // Update the drawing caches
- view.buildDrawingCache(true);
- }
- }
- void clearChildrenCache(){
- final int count = getChildCount();
- for(int i =0; i < count; i++){
- final CellLayout layout =(CellLayout) getChildAt(i);
- layout.setChildrenDrawnWithCacheEnabled(false);
- }
- }
截屏代码实现
- publicclassScreenShot{
- // 获取指定Activity的截屏,保存到png文件
- publicstaticBitmap takeScreenShot(Activity activity){
- // View是你需要截图的View
- View view = activity.getWindow().getDecorView();
- view.setDrawingCacheEnabled(true);
- view.buildDrawingCache();
- Bitmap b1 = view.getDrawingCache();
- // 获取状态栏高度
- Rect frame =newRect();
- activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
- int statusBarHeight = frame.top;
- System.out.println(statusBarHeight);
- // 获取屏幕长和高
- int width = activity.getWindowManager().getDefaultDisplay().getWidth();
- int height = activity.getWindowManager().getDefaultDisplay()
- .getHeight();
- // 去掉标题栏
- // Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);
- Bitmap b =Bitmap.createBitmap(b1,0, statusBarHeight, width, height
- - statusBarHeight);
- view.destroyDrawingCache();
- savePic(b,"/sdcard/screen_test.png");
- return b;
- }
- // 保存到sdcard
- publicstaticvoid savePic(Bitmap b,String strFileName){
- FileOutputStream fos =null;
- try{
- fos =newFileOutputStream(strFileName);
- if(null!= fos){
- b.compress(Bitmap.CompressFormat.PNG,90, fos);
- fos.flush();
- fos.close();
- }
- }catch(FileNotFoundException e){
- e.printStackTrace();
- }catch(IOException e){
- e.printStackTrace();
- }
- }
- /**
- * 把View对象转换成bitmap
- * */
- publicstaticBitmap convertViewToBitmap(View view){
- view.measure(MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED),
- MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED));
- view.layout(0,0, view.getMeasuredWidth(), view.getMeasuredHeight());
- view.buildDrawingCache();
- Bitmap bitmap = view.getDrawingCache();
- if(bitmap !=null){
- System.out.println("这不是nullde1");
- Log.d("nullde1","nullde1");
- }else{
- System.out.println("这nullnulllnulnlul");
- }
- return bitmap;
- }
- // 程序入口1
- publicstaticvoid shoot(Activity a){
- ScreenShot.savePic(ScreenShot.takeScreenShot(a),"/sdcard/screen_test.png");
- }
- // 程序入口2
- publicstaticvoid shootView(View view){
- ScreenShot.savePic(ScreenShot.convertViewToBitmap(view),
- "sdcard/xx.png");
- }
- publicstaticBitmap getViewBitmap(View v){
- v.clearFocus();
- v.setPressed(false);
- boolean willNotCache = v.willNotCacheDrawing();
- v.setWillNotCacheDrawing(false);
- // Reset the drawing cache background color to fully transparent
- // for the duration of this operation
- int color = v.getDrawingCacheBackgroundColor();
- v.setDrawingCacheBackgroundColor(0);
- if(color !=0){
- v.destroyDrawingCache();
- }
- v.buildDrawingCache();
- Bitmap cacheBitmap = v.getDrawingCache();
- if(cacheBitmap ==null){
- Log.e("TTTTTTTTActivity","failed getViewBitmap("+ v +")",
- newRuntimeException());
- returnnull;
- }
- Bitmap bitmap =Bitmap.createBitmap(cacheBitmap);
- // Restore the view
- v.destroyDrawingCache();
- v.setWillNotCacheDrawing(willNotCache);
- v.setDrawingCacheBackgroundColor(color);
- return bitmap;
- }
- /**
- * 截取scrollview的屏幕
- * **/
- publicstaticBitmap getBitmapByView(ScrollView scrollView){
- int h =0;
- Bitmap bitmap =null;
- // 获取listView实际高度
- for(int i =0; i < scrollView.getChildCount(); i++){
- h += scrollView.getChildAt(i).getHeight();
- scrollView.getChildAt(i).setBackgroundResource(R.drawable.bg3);
- }
- Log.d(TAG,"实际高度:"+ h);
- Log.d(TAG," 高度:"+ scrollView.getHeight());
- // 创建对应大小的bitmap
- bitmap =Bitmap.createBitmap(scrollView.getWidth(), h,
- Bitmap.Config.ARGB_8888);
- finalCanvas canvas =newCanvas(bitmap);
- scrollView.draw(canvas);
- // 测试输出
- FileOutputStream out =null;
- try{
- out =newFileOutputStream("/sdcard/screen_test.png");
- }catch(FileNotFoundException e){
- e.printStackTrace();
- }
- try{
- if(null!= out){
- bitmap.compress(Bitmap.CompressFormat.PNG,100, out);
- out.flush();
- out.close();
- }
- }catch(IOException e){
- // TODO: handle exception
- }
- return bitmap;
- }
- privatestaticString TAG ="Listview and ScrollView item 截图:";
- /**
- * 截图listview
- * **/
- publicstaticBitmap getbBitmap(ListView listView){
- int h =0;
- Bitmap bitmap =null;
- // 获取listView实际高度
- for(int i =0; i < listView.getChildCount(); i++){
- h += listView.getChildAt(i).getHeight();
- }
- Log.d(TAG,"实际高度:"+ h);
- Log.d(TAG,"list 高度:"+ listView.getHeight());
- // 创建对应大小的bitmap
- bitmap =Bitmap.createBitmap(listView.getWidth(), h,
- Bitmap.Config.ARGB_8888);
- finalCanvas canvas =newCanvas(bitmap);
- listView.draw(canvas);
- // 测试输出
- FileOutputStream out =null;
- try{
- out =newFileOutputStream("/sdcard/screen_test.png");
- }catch(FileNotFoundException e){
- e.printStackTrace();
- }
- try{
- if(null!= out){
- bitmap.compress(Bitmap.CompressFormat.PNG,100, out);
- out.flush();
- out.close();
- }
- }catch(IOException e){
- // TODO: handle exception
- }
- return bitmap;
- }
- }
view及其子类的LayoutParams的设置
- LayoutParamsParam=(RelativeLayout.LayoutParams) live_broadcase.getLayoutParams();
- float live_broadcase_lenght=live_broadcase.getTextSize()*s[2].length();
- if(screen_width<live_broadcase_lenght){
- Param.setMargins(Param.leftMargin,Param.topMargin,(int)-live_broadcase_lenght+screen_width,Param.bottomMargin);
- live_broadcase.setLayoutParams(Param);
- }
view的ViewConfiguration
- ViewConfiguration config =ViewConfiguration.get(context);
- mTouchSlop = config.getScaledTouchSlop();
代码控制布局
- RelativeLayout container =newRelativeLayout(this);
- Button btn1 =newButton(this);
- btn1.setId(11);
- btn1.setText("上");
- Button btn2 =newButton(this);
- btn2.setId(12);
- btn2.setText("下");
- Button btn3 =newButton(this);
- btn3.setId(13);
- btn3.setText("左");
- Button btn4 =newButton(this);
- btn4.setId(14);
- btn4.setText("右");
- Button btn5 =newButton(this);
- btn5.setId(15);
- btn5.setText("中");
- RelativeLayout.LayoutParams lp1 =newRelativeLayout.LayoutParams(100,
- RelativeLayout.LayoutParams.WRAP_CONTENT);
- RelativeLayout.LayoutParams lp2 =newRelativeLayout.LayoutParams(lp1);
- RelativeLayout.LayoutParams lp3 =newRelativeLayout.LayoutParams(lp1);
- RelativeLayout.LayoutParams lp4 =newRelativeLayout.LayoutParams(lp1);
- RelativeLayout.LayoutParams lp5 =newRelativeLayout.LayoutParams(lp1);
- lp5.addRule(RelativeLayout.CENTER_IN_PARENT,RelativeLayout.TRUE);
- lp1.addRule(RelativeLayout.ABOVE, btn5.getId());
- lp1.addRule(RelativeLayout.ALIGN_LEFT, btn5.getId());
- lp2.addRule(RelativeLayout.BELOW, btn5.getId());
- lp2.addRule(RelativeLayout.ALIGN_LEFT, btn5.getId());
- lp3.addRule(RelativeLayout.LEFT_OF, btn5.getId());
- lp3.addRule(RelativeLayout.ALIGN_BASELINE, btn5.getId());
- lp4.addRule(RelativeLayout.RIGHT_OF, btn5.getId());
- lp4.addRule(RelativeLayout.ALIGN_TOP, btn5.getId());
- container.addView(btn5, lp5);
- container.addView(btn1, lp1);
- container.addView(btn2, lp2);
- container.addView(btn3, lp3);
- container.addView(btn4, lp4);
- return container;
addView的理解
public void addView (View child, int index, ViewGroup.LayoutParams params)
这里最主要的参数就是index,标示的是希望将view增加到哪个view的下面。从刚才的布局代码片段看,以父布局relativelayout算起,
即
RelativeLayou index=0;
GridView index=1;
LinearLayout index=2;
你如果给index填写大于2的值将会报错。因为在当前父容器下,没有大于3的同级view
当然你还可以填写index=-1,-1的意思是,将view加到父容器中所有容器的最下面,也就是linearlayout的下面
footView一般调用addView(child, -1, params);
- public void addView(View child) {
- addView(child, -1);
- }
根据不同的需求加载布局到当前界面,并且保证不找错xml的情况下加载布局里面的控件
- <?xml version="1.0" encoding="utf-8"?>
- <mergexmlns:android="http://schemas.android.com/apk/res/android">
- <FrameLayout
- android:id="@+id/fl_inner"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:paddingBottom="@dimen/header_footer_top_bottom_padding"
- android:paddingLeft="@dimen/header_footer_left_right_padding"
- android:paddingRight="@dimen/header_footer_left_right_padding"
- android:paddingTop="@dimen/header_footer_top_bottom_padding">
- <ImageView
- android:id="@+id/pull_to_refresh_image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"/>
- <ProgressBar
- android:id="@+id/pull_to_refresh_progress"
- style="?android:attr/progressBarStyleSmall"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:indeterminate="true"
- android:visibility="gone"/>
- </FrameLayout>
- </merge>
- <?xml version="1.0" encoding="utf-8"?>
- <mergexmlns:android="http://schemas.android.com/apk/res/android">
- <FrameLayout
- android:id="@+id/fl_inner"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="@dimen/header_footer_top_bottom_padding"
- android:paddingLeft="@dimen/header_footer_left_right_padding"
- android:paddingRight="@dimen/header_footer_left_right_padding"
- android:paddingTop="@dimen/header_footer_top_bottom_padding">
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="left|center_vertical">
- <ImageView
- android:id="@+id/pull_to_refresh_image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"/>
- <ProgressBar
- android:id="@+id/pull_to_refresh_progress"
- style="?android:attr/progressBarStyleSmall"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:indeterminate="true"
- android:visibility="gone"/>
- </FrameLayout>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:gravity="center_horizontal"
- android:orientation="vertical">
- <TextView
- android:id="@+id/pull_to_refresh_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:textAppearance="?android:attr/textAppearance"
- android:textStyle="bold"/>
- <TextView
- android:id="@+id/pull_to_refresh_sub_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:visibility="gone"/>
- </LinearLayout>
- </FrameLayout>
- </merge>
- public abstract class LoadingLayout extends FrameLayout implements ILoadingLayout {
- publicLoadingLayout(Context context,finalMode mode,finalOrientation scrollDirection,TypedArray attrs){
- super(context);
- mMode = mode;
- mScrollDirection = scrollDirection;
- switch(scrollDirection){
- case HORIZONTAL:
- LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_horizontal,this);
- break;
- case VERTICAL:
- default:
- LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_vertical,this);
- break;
- }
- mInnerLayout =(FrameLayout) findViewById(R.id.fl_inner);
- mHeaderText =(TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_text);
- mHeaderProgress =(ProgressBar) mInnerLayout.findViewById(R.id.pull_to_refresh_progress);
- mSubHeaderText =(TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_sub_text);
- mHeaderImage =(ImageView) mInnerLayout.findViewById(R.id.pull_to_refresh_image);
viewstub的理解
Android性能优化之一:ViewStub
ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View。虽然Android开发人员基本上都听说过,但是真正用的可能不多。
ViewStub可以理解成一个非常轻量级的View,与其他的控件一样,有着自己的属性及特定的方法。当ViewStub使用在布局文件中时,当程序inflate布局文件时,ViewStub本身也会被解析,且占据内存控件,但是与其他控件相比,主要区别体现在以下几点:
1.当布局文件inflate时,ViewStub控件虽然也占据内存,但是相相比于其他控件,ViewStub所占内存很小;
2.布局文件inflate时,ViewStub主要是作为一个“占位符”的性质,放置于view tree中,且ViewStub本身是不可见的。ViewStub中有一个layout属性,指向ViewStub本身可能被替换掉的布局文件,在一定时机时,通过viewStub.inflate()完成此过程;
3.ViewStub本身是不可见的,对ViewStub setVisibility(..)与其他控件不一样,ViewStub的setVisibility 成View.VISIBLE或INVISIBLE如果是首次使用,都会自动inflate其指向的布局文件,并替换ViewStub本身,再次使用则是相当于对其指向的布局文件设置可见性。
这里需要注意的是:
1.ViewStub之所以常称之为“延迟化加载”,是因为在教多数情况下,程序无需显示ViewStub所指向的布局文件,只有在特定的某些较少条件下,此时ViewStub所指向的布局文件才需要被inflate,且此布局文件直接将当前ViewStub替换掉,具体是通过viewStub.infalte()或viewStub.setVisibility(View.VISIBLE)来完成;
2.正确把握住ViewStub的应用场景非常重要,正如如1中所描述需求场景下,使用ViewStub可以优化布局;
3.对ViewStub的inflate操作只能进行一次,因为inflate的时候是将其指向的布局文件解析inflate并替换掉当前ViewStub本身(由此体现出了ViewStub“占位符”性质),一旦替换后,此时原来的布局文件中就没有ViewStub控件了,因此,如果多次对ViewStub进行infalte,会出现错误信息:ViewStub must have a non-null ViewGroup viewParent。
4.3中所讲到的ViewStub指向的布局文件解析inflate并替换掉当前ViewStub本身,并不是完全意义上的替换(与include标签还不太一样),替换时,布局文件的layout params是以ViewStub为准,其他布局属性是以布局文件自身为准。
下面看一下简单的需求场景:在listview显示列表数据时,可能会出现服务端一条数据都没有的情况,此时显示一个EmptyView,提示用户暂无数据。此时考虑到实际应用中EmptyView显示出来的机会相当小,因此,可以在布局文件中使用ViewStub站位,然后确实没有数据时才viewStub.infalte()。
相关部分代码如下:
 1 public void showEmptyView() {
 2     listview.setVisibility(View.GONE);
 3     if (noDataView == null) {
 4         ViewStub noDataViewStub = (ViewStub) view.findViewById(R.id.no_data_viewstub);
 5         noDataView = noDataViewStub.inflate();
 6     } else {
 7         noDataView.setVisibility(View.VISIBLE);
 8     }
 9 }
1011 public void showListView(){
12     listview.setVisibility(View.VISIBLE);
13     if(noDataView != null){
14         noDataView.setVisibility(View.GONE);
15     }
16 }
特别需要注意的是对ViewStub是否已经inflate的判断。
在Listview Item中,有时候可能遇到如下场景:在不同的列表页item的布局一部分不同,但相对于整个item布局来说又不是很多,此时最常见的有如下两种处理:
1.对不同的部分都写出来,放到一个item文件中,然后逻辑分别处理不同部分的显示与否(View.VISIBLE和View.GONE);
2.对这两种不同的item整个部分都分别区分开,完全写成两个item文件,然后结合listView显示不同布局分别做逻辑处理(通过getItemType()等方式)。
以上两种处理方式其实都可以,第一种方式逻辑清晰,非常灵活,只是在一定程度上增加了内存和资源消耗。第二种方式是的布局文件有重复(虽然相同部分可以通过include,但是逻辑上还是有重复的),包括逻辑上处理的代码实质上的重复。一般对于有较大不同的item布局推荐采用此种方式。
有时候结合需求,可以在第一种方式的基础上,结合ViewStub“占位符”可以比较好的完成此类需求。也相当于是两种方式的一种折中形式,但同时兼顾了内存和资源消耗以及不同的布局逻辑控件。
在代码中新建一个控件对象,和布局控件(xml中的)的位置一样的
- //m.setLayoutParams(lp);
- //RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(250, 250);
- //lp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
- //lp.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
- //lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
- //m.setX(x);
- //int[] fromViewLocation = new int[2];
- //liveactivity.getLocationOnScreen(fromViewLocation);
- //m.setX(fromViewLocation[0]/2);
- //m.setY(fromViewLocation[1]/2);
- android.view.ViewGroup.LayoutParams lp= live_gift_display.getLayoutParams();
- ImageView m=newImageView(this);
- m.setLayoutParams(lp);
- m.setScaleType(ScaleType.FIT_CENTER);
- m.setImageDrawable(d);
- liveactivity.addView(m);
- m.layout(live_gift_display.getLeft(), live_gift_display.getTop(), live_gift_display.getRight(), live_gift_display.getBottom());
改变控件的高和宽
- RelativeLayout.LayoutParams linearParams =(RelativeLayout.LayoutParams) baseBtn.getLayoutParams();//取控件textView当前的布局参数
- linearParams.height = getResources().getDimensionPixelSize(R.dimen.height_20dp);// 控件的高强制设成20
- linearParams.width = getResources().getDimensionPixelSize(R.dimen.width_20dp);// 控件的宽强制设成30
- baseBtn.setLayoutParams(linearParams);
OnGlobalLayoutListener获得一个视图的高度
- privateint mHeaderViewHeight;
- privateView mHeaderView;
- .....
- mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(
- newOnGlobalLayoutListener(){
- @Override
- publicvoid onGlobalLayout(){
- mHeaderViewHeight = mHeaderView.getHeight();
- mHeaderView.getViewTreeObserver()
- .removeGlobalOnLayoutListener(this);
- }
- });
ViewGroup为什么不会调用onDraw
onLayout的含义(ViewGroup:可布局的区域 view:布局的位置)
- @Override
- protected abstract void onLayout(boolean changed,
- int l,int t,int r,int b);
- publicvoid layout(int l,int t,int r,int b);
 
                    
                     
                    
                 
                    
                

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号