View,viewgroup,viewstub总结
:first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; max-width: 100%; height: auto !important; margin: 2px 0; } table { border-collapse: collapse; border: 1px solid #bbbbbb; } td { padding: 4px 8px; border-collapse: collapse; border: 1px solid #bbbbbb; } @media screen and (max-width: 660px) { body { padding: 20px 18px; padding: 1.33rem 1.2rem; } } @media only screen and (-webkit-max-device-width: 1024px), only screen and (-o-max-device-width: 1024px), only screen and (max-device-width: 1024px), only screen and (-webkit-min-device-pixel-ratio: 3), only screen and (-o-min-device-pixel-ratio: 3), only screen and (min-device-pixel-ratio: 3) { html, body { font-size: 17px; } body { line-height: 1.7; padding: 0.75rem 0.9375rem; color: #353c47; } h1 { font-size: 2.125rem; } h2 { font-size: 1.875rem; } h3 { font-size: 1.625rem; } h4 { font-size: 1.375rem; } h5 { font-size: 1.125rem; } h6 { color: inherit; } ul, ol { padding-left: 2.5rem; } blockquote { padding: 0 0.9375rem; } }
-->
- 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);
View,viewgroup,viewstub总结的更多相关文章
- java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.L(转)
09-09 10:19:59.979: E/AndroidRuntime(2767): FATAL EXCEPTION: main09-09 10:19:59.979: E/AndroidRuntim ...
- 自定义View/ViewGroup的步骤和实现
1.设置属性(供XML调用) 在res目录新建attrs.xml文件 <?xml version="1.0" encoding="utf-8"?> ...
- View,ViewGroup的Touch事件的分发机制
原帖地址:http://blog.csdn.net/xiaanming/article/details/21696315 ViewGroup的事件分发机制 我们用手指去触摸Android手机屏幕,就会 ...
- LayoutParams继承于Android.View.ViewGroup.LayoutParams(转)
LayoutParams相当于一个Layout的信息包,它封装了Layout的位置.高.宽等信息.假设在屏幕上一块区域是由一个Layout占领的,如果将一个View添加到一个Layout中,最好告诉L ...
- extends android.view.ViewGroup两种实现
/* private int measureHeight(int heightMeasureSpec) { int count = getChildCount(); ...
- Andriod 从源码的角度详解View,ViewGroup的Touch事件的分发机制
转自:xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/21696315) 今天这篇文章主要分析的是Android的事件分发机制, ...
- LayoutParams继承于Android.View.ViewGroup.LayoutParams.
LayoutParams相当于一个Layout的信息包,它封装了Layout的位置.高.宽等信息.假设在屏幕上一块区域是由一个Layout占领的,如果将一个View添加到一个Layout中,最好告诉L ...
- 解决 android.view.ViewGroup$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
错误日志1: 06-13 10:55:50.410: E/KVLog(1129): Error info:java.lang.ClassCastException: android.widget.Li ...
- Android View和ViewGroup
View和ViewGroup Android的UI界面都是由View和ViewGroup及其派生类组合而成的. 其中,View是所有UI组件的基类,而 ViewGroup是容纳这些组件的容器,其本身也 ...
随机推荐
- memcached-win32-1.4.4-14 help doc
memcached-win32-1.4.4-14 cmd打开命令窗口,转到解压的目录,输入 “memcached.exe -d install”. 使用telnet命令 验证缓存服务器是否可用.tel ...
- android中viewPager+fragment实现的屏幕左右切换(进阶篇)
Fragment支持在不同的Activity中使用并且可以处理自己的输入事件以及生命周期方法等.可以看做是一个子Activity. 先看一下布局: 1 <LinearLayout xmlns:a ...
- JAVA 反序列化攻击
Java 反序列化攻击漏洞由 FoxGlove 的最近的一篇博文爆出,该漏洞可以被黑客利用向服务器上传恶意脚本,或者远程执行命令. 由于目前发现该漏洞存在于 Apache commons-collec ...
- 【UVA 10600】 ACM Contest and Blackout(最小生成树和次小生成树)
[题意] n个点,m条边,求最小生成树的值和次小生成树的值. InputThe Input starts with the number of test cases, T (1 < T < ...
- http://blog.csdn.net/dyllove98/article/details/7706218
http://blog.csdn.net/dyllove98/article/details/7706218
- Java使用JAX-WS来写webservice时 Unable to create JAXBContext
webservice,作为web开发人员来说必须掌握的一门技术,它的好处这里就不多说了,eclipse中自带了一种生成webservice的 方法,使用JAX-WS,如果我没有弄错的话,它需要java ...
- linux使用ps1设置命令行提示符
要自定义命令行提示,需要ps1来设置.完成自定义需要以下几个步骤: 1.编辑~/.bashrc文件 vi ~/.bashrc 2.在.bashrc文件中添加以下一行自定义内容 export PS1=& ...
- 码云分布式之 Brzo 服务器
摘要: 码云是国内最大的代码托管平台,为了支持更大的用户规模,开发团队也在对一些组件进行大规模的重构. 前言 码云是国内最大的代码托管平台.码云基于 Gitlab 5.5 开发,经过几年的开发已经和官 ...
- IP处理函数inet_aton()和inet_ntoa(),inet_pton,inet_ntop
inet_ntoa: 功能: 将一个IP转换成一个互联网标准点分格式的字符串. 原型: char FAR * inet_ntoa( struct in_addr in); 返回值: 如果正确,返回一个 ...
- Android源码之Matrix
Matrix类在Android中主要用来进行矩阵变换,其可操作的对象包括图像.点阵.Vector(向量).矩形等. Matrix支持的变换类型主要有以下几种: 1.Translate:平移变换 2.R ...