在Android中怎么获得控件宽高呢?第一反应是使用View.getWIdht()或View.getHeight()来获得。好,敲好代码如下
- <span style="font-size:18px;">private LinearLayout layout;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- layout = (LinearLayout) findViewById(R.id.layout);
- int width = layout.getWidth();
- int height = layout.getHeight();
- Log.i("man", "width=" + width + ";height=" + height);</span>
<span style="font-size:18px;">private LinearLayout layout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); layout = (LinearLayout) findViewById(R.id.layout); int width = layout.getWidth(); int height = layout.getHeight(); Log.i("man", "width=" + width + ";height=" + height);</span>
可是结果确实这样
01-08 23:22:20.256: W/ApplicationPackageManager(13371): getCSCPackageItemText()
01-08 23:22:20.296: E/MoreInfoHPW_ViewGroup(13371): Parent view is not a TextView
01-08 23:22:20.306: I/man(13371): width=0;height=0
咦!怎么回事?接着在onStart()和onResume()方法中试验了下,
01-08 23:25:26.046: I/man onStart(15544): width=0;height=0
01-08 23:25:26.046: I/man onResume(15544): width=0;height=0
有没有很奇怪?原来Android程序的运行机制决定了无法再组件类外部使用getWidth()和getHeight()来获得宽度和高度(在自定义组件类的内容可以通过这两个方法获取当前组件的宽度和高度,如在onSizeChanged方法中可以使用这两个方法获得宽度和高度),必须使用View.getMeasuredWidth()和View.getMeasuredHeight()。当然,光有这两个方法还是不够的,在这之前还必须调用View.measure方法先测量组件的宽度和高度。好,现在加上了这些方法再试下:
- <span style="font-size:18px;"> private LinearLayout layout;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- layout = (LinearLayout) findViewById(R.id.layout);
- int width = layout.getWidth();
- int height = layout.getHeight();
- Log.i("man", "width=" + width + ";height=" + height);
- layout.measure(0, 0);
- width = layout.getMeasuredWidth();
- height = layout.getMeasuredHeight();
- Log.i("man", "width=" + width + ";height=" + height);</span>
<span style="font-size:18px;"> private LinearLayout layout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); layout = (LinearLayout) findViewById(R.id.layout); int width = layout.getWidth(); int height = layout.getHeight(); Log.i("man", "width=" + width + ";height=" + height); layout.measure(0, 0); width = layout.getMeasuredWidth(); height = layout.getMeasuredHeight(); Log.i("man", "width=" + width + ";height=" + height);</span>
01-08 23:36:50.856: I/man(16487): width=0;height=0
01-08 23:36:50.856: I/man(16487): width=462;height=240
好像是获取到了,不为0了,但是我又发现了个问题,先看我的布局文件:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/layout"
- tools:context="com.huxq.screenshot.MainActivity" >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/hello_world" />
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/ic_launcher" />
- </LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/layout" tools:context="com.huxq.screenshot.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> </LinearLayout>
明明LInearLayout是全屏的啊,而且我用的测试机是Galaxy Note3,分辨率是1920x1080像素的,怎么只有462x240呢?
后来发现,如果控件的宽度或高度设为fill_parent或match_parent,使用getMeasuredWidth或getMeasuredHeight方法获取组件宽度或高度时,当组建中包含其他子组件时,所获得的实际值是这鞋组件所占的最小宽度和最小高度。
还有一种方法也可以获取在布局文件中定义的组件的宽度和高度,直接使用View.getLayoutParams().width和View.getLayoutParams().height。但是当宽度和高度被设为match_parent或wrap_content时,这两个变量返回的是MATCH_PARENT和WRAP_CONTENT常量的值,这并不是我们想要的。
接下来介绍在Android中实现截屏功能的一种很简单却实用的方法。
Android允许直接将布局中的View存在图片,因此在Android SDK中提供了API直接将可视组件绘制到bitmap上。绘制可视组件主要涉及到View.setDrawingCacheEnabled方法和View.getDrawingCache方法。下面看代码:
- private LinearLayout layout;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- layout = (LinearLayout) findViewById(R.id.layout);
- int width = layout.getWidth();
- int height = layout.getHeight();
- Log.i("man", "width=" + width + ";height=" + height);
- //打开图像缓存
- layout.setDrawingCacheEnabled(true);
- //测量Linearlayout的大小
- layout.measure(0, 0);
- width = layout.getMeasuredWidth();
- height = layout.getMeasuredHeight();
- Log.i("man", "width=" + width + ";height=" + height);
- //发送位置和尺寸到LienarLayout及其所有的子View
- //简单地说,就是我们截取的屏幕区域,注意是以Linearlayout左上角为基准的,而不是屏幕左上角
- layout.layout(0, 0, width, height);
- //拿到截取图像的bitmap
- Bitmap bitmap = layout.getDrawingCache();
- FileOutputStream fos = null;
- //获得sd卡路径
- String rootPath = Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED) ? Environment
- .getExternalStorageDirectory().getAbsolutePath() : null;
- //不存在文件夹就新建一个
- try {
- File file = new File(rootPath + "/screenShot/");
- if (!file.exists()) {
- file.mkdirs();
- }
- fos = new FileOutputStream(rootPath + "/screenShot/"
- + System.currentTimeMillis() + ".png");
- //把bitmap压缩成png格式,并通过fos写入到目标文件
- bitmap.compress(CompressFormat.PNG, 100, fos);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } finally {
- if (fos != null) {
- try {
- fos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
private LinearLayout layout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); layout = (LinearLayout) findViewById(R.id.layout); int width = layout.getWidth(); int height = layout.getHeight(); Log.i("man", "width=" + width + ";height=" + height); //打开图像缓存 layout.setDrawingCacheEnabled(true); //测量Linearlayout的大小 layout.measure(0, 0); width = layout.getMeasuredWidth(); height = layout.getMeasuredHeight(); Log.i("man", "width=" + width + ";height=" + height); //发送位置和尺寸到LienarLayout及其所有的子View //简单地说,就是我们截取的屏幕区域,注意是以Linearlayout左上角为基准的,而不是屏幕左上角 layout.layout(0, 0, width, height); //拿到截取图像的bitmap Bitmap bitmap = layout.getDrawingCache(); FileOutputStream fos = null; //获得sd卡路径 String rootPath = Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED) ? Environment .getExternalStorageDirectory().getAbsolutePath() : null; //不存在文件夹就新建一个 try { File file = new File(rootPath + "/screenShot/"); if (!file.exists()) { file.mkdirs(); } fos = new FileOutputStream(rootPath + "/screenShot/" + System.currentTimeMillis() + ".png"); //把bitmap压缩成png格式,并通过fos写入到目标文件 bitmap.compress(CompressFormat.PNG, 100, fos); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } }
最后要提醒大家一点就是manifest文件中不要忘了添加读写sd卡的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
本文来自:
http://blog.csdn.net/footballclub/article/details/42536671
//------------------------------------------------------------------------------------------------------------
Android 获取控件的宽和高
我们都知道在onCreate()里面获取控件的高度是0,这是为什么呢?我们来看一下示例:
首先我们自己写一个控件,这个控件非常简单:
- public class MyImageView extends ImageView {
- public MyImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public MyImageView(Context context) {
- super(context);
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- System.out.println("onMeasure 我被调用了"+System.currentTimeMillis());
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- System.out.println("onDraw 我被调用了"+System.currentTimeMillis());
- }
- }
public class MyImageView extends ImageView { public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); } public MyImageView(Context context) { super(context); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); System.out.println("onMeasure 我被调用了"+System.currentTimeMillis()); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); System.out.println("onDraw 我被调用了"+System.currentTimeMillis()); } }
布局文件:
- <com.test.MyImageView
- android:id="@+id/imageview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/test" />
<com.test.MyImageView android:id="@+id/imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/test" />
测试的Activity的onCreate():
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- System.out.println("执行完毕.."+System.currentTimeMillis());
- }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); System.out.println("执行完毕.."+System.currentTimeMillis()); }
现在我们现在来看一下结果:
说明等onCreate方法执行完了,我们定义的控件才会被度量(measure),所以我们在onCreate方法里面通过view.getHeight()获取控件的高度或者宽度肯定是0,因为它自己还没有被度量,也就是说他自己都不知道自己有多高,而你这时候去获取它的尺寸,肯定是不行的.
现在碰到这个问题我们不能不解决,在网上找到了如下办法:
- //------------------------------------------------方法一
- int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
- int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
- imageView.measure(w, h);
- int height =imageView.getMeasuredHeight();
- int width =imageView.getMeasuredWidth();
- textView.append("\n"+height+","+width);
- //-----------------------------------------------方法二
- ViewTreeObserver vto = imageView.getViewTreeObserver();
- vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
- public boolean onPreDraw() {
- int height = imageView.getMeasuredHeight();
- int width = imageView.getMeasuredWidth();
- textView.append("\n"+height+","+width);
- return true;
- }
- });
- //-----------------------------------------------方法三
- ViewTreeObserver vto2 = imageView.getViewTreeObserver();
- vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
- textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth());
- }
- });
//------------------------------------------------方法一 int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); imageView.measure(w, h); int height =imageView.getMeasuredHeight(); int width =imageView.getMeasuredWidth(); textView.append("\n"+height+","+width); //-----------------------------------------------方法二 ViewTreeObserver vto = imageView.getViewTreeObserver(); vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { int height = imageView.getMeasuredHeight(); int width = imageView.getMeasuredWidth(); textView.append("\n"+height+","+width); return true; } }); //-----------------------------------------------方法三 ViewTreeObserver vto2 = imageView.getViewTreeObserver(); vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this); textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth()); } });
这三个方法是哪里找到现在已经忘了.
现在要讨论的是当我们需要时候使用哪个方法呢?
现在把测试的Activity改成如下:
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final ImageView imageView = (ImageView) findViewById(R.id.imageview);
- //------------------------------------------------方法一
- int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
- int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
- imageView.measure(w, h);
- int height =imageView.getMeasuredHeight();
- int width =imageView.getMeasuredWidth();
- textView.append("\n"+height+","+width);
- System.out.println("执行完毕.."+System.currentTimeMillis());
- }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final ImageView imageView = (ImageView) findViewById(R.id.imageview); //------------------------------------------------方法一 int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); imageView.measure(w, h); int height =imageView.getMeasuredHeight(); int width =imageView.getMeasuredWidth(); textView.append("\n"+height+","+width); System.out.println("执行完毕.."+System.currentTimeMillis()); }
接着来看下面几种方式输出结果:
把测试Activity改成如下:
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final ImageView imageView = (ImageView) findViewById(R.id.imageview);
- -----------------------------------------------方法二
- ViewTreeObserver vto = imageView.getViewTreeObserver();
- vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
- public boolean onPreDraw() {
- int height = imageView.getMeasuredHeight();
- int width = imageView.getMeasuredWidth();
- textView.append("\n"+height+","+width);
- return true;
- }
- });
- }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final ImageView imageView = (ImageView) findViewById(R.id.imageview); //-----------------------------------------------方法二 ViewTreeObserver vto = imageView.getViewTreeObserver(); vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { int height = imageView.getMeasuredHeight(); int width = imageView.getMeasuredWidth(); textView.append("\n"+height+","+width); return true; } }); }
结果如下:
方法三就不再测试了同方法二!!!
那么方法而和方法三在执行上有什么区别呢?
我们在布局文件中加入一个TextView来记录这个控件的宽高.
- <ScrollView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
- <TextView
- android:id="@+id/text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </ScrollView>
<ScrollView android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </ScrollView>
先来测试方法而:
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final ImageView imageView = (ImageView) findViewById(R.id.imageview);
- -----------------------------------------------方法二
- ViewTreeObserver vto = imageView.getViewTreeObserver();
- vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
- public boolean onPreDraw() {
- int height = imageView.getMeasuredHeight();
- int width = imageView.getMeasuredWidth();
- textView.append("\n"+height+","+width);
- return true;
- }
- });
- }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final ImageView imageView = (ImageView) findViewById(R.id.imageview); //-----------------------------------------------方法二 ViewTreeObserver vto = imageView.getViewTreeObserver(); vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { int height = imageView.getMeasuredHeight(); int width = imageView.getMeasuredWidth(); textView.append("\n"+height+","+width); return true; } }); }
结果如下:
我们再来测试方法三
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- final ImageView imageView = (ImageView) findViewById(R.id.imageview);
- //-----------------------------------------------方法三
- ViewTreeObserver vto2 = imageView.getViewTreeObserver();
- vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
- textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth());
- }
- });
- }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final ImageView imageView = (ImageView) findViewById(R.id.imageview); //-----------------------------------------------方法三 ViewTreeObserver vto2 = imageView.getViewTreeObserver(); vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this); textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth()); } }); }
输出结果如下:
我想这方法二和方法三之间的区别就不用说了吧.
总结:那么需要获取控件的宽高该用那个方法呢?
方法一: 比其他的两个方法多了一次计算,也就是多调用了一次onMeasure()方法,该方法虽然看上去简单,但是如果要目标控件计算耗时比较大的话(如listView等),不建议使用.
方法二,它的回调方法会调用很多次,并且滑动TextView的时候任然会调用,所以不建议使用.
方法三,比较合适.
当然,实际应用的时候需要根据实际情况而定.
谢谢!! 欢迎转载:http://blog.csdn.net/johnny901114/article/details/7839512
Android开发在任意类中获取当前屏幕宽高
进行Android编程时,很多时候都需要获取当前屏幕的宽度与高度,但是当我们需要在别的类中调用屏幕宽高时,直接用原来的方法是不行的,下面我来介绍如何在任意类中调用宽度高度的两种方法
public void getScreenHW(Context context){ WindowManager manager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); Display display = manager.getDefaultDisplay(); int width =display.getWidth(); int height=display.getHeight(); Log.d("width", String.valueOf(width)); Log.d("height", String.valueOf(height)); //第一种 DisplayMetrics dm=new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(dm); int width2=dm.widthPixels; int height2=dm.heightPixels; Log.d("width2", String.valueOf(width2)); Log.d("height2", String.valueOf(height2)); //第二种 }
需要注意的时,当我的targetSdkVersion是17 也就是4.2.2的时候,第一种方法已经被废除了,建议采用第二种方法
Android
程序中要设置全屏包括两个部分:
窗口全屏和Activity全屏。
窗口全屏是指隐藏系统顶部用来显示时间、电量、信号等信息的标题栏,Activity全屏是
指隐藏程序的标题栏。我们可以在程序代码中设置,也可以通过修改AndroidManifest.xml
文件来实现。
1.
修改程序代码
我们需要在Activity的onCreate方法中添加相应的代码。请注意代码的位置,要在setContentView(调用哦。
Java代码
1.
public class Home extends Activity {
2.
3.@Override
4.protected void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. requestWindowFeature(Window.FEATURE_NO_TITLE);//不显示程序的标题栏
7. getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN ,WindowManageroutParams. FLAG_FULLSCREEN);//不显示系统的标题栏
8.setContentView(R.layout.main);
9. }
10.
11. }
复制代码
2. 修改 AndroidManifest.xml 。 我们可以修改<application>标签或<activity>标签的属性值来实现。他们的区别是修改<application>标签后所有的Activity都会全屏,而修改<activity>后只针对当前的Activity有效。注意:android:theme="@android:style/Theme.NoTitleBar.Fullscreen"的位置,我在两处都设置上了,大家可以根据实际状况做出调整。
Xml代码
1. <?xml version="1.0" encoding="utf-8"?>
2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3. package="org.dw.enotes"
4. android:versionCode="1"
5. android:versionName="1.0">
6. <application android:icon="@drawable/icon"
7. android:label="@string/app_name"
8. <!-- 看这里 -->
9. android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
10.
11. <activity
12. android:name=".activity.Hello"
13. android:label="@string/app_name"
14.
<!-- 看这里 -->
15. android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
16. <intent-filter>
17. <action android:name="android.intent.action.MAIN" />
18.
<category android:name="android.intent.category.LAUNCHER" />
19. </intent-filter>
20. </activity>
21. </application>
22. <uses-sdk android:minSdkVersion="4" />
23. </manifest> 复制代码 Android获得屏幕的宽度和高度很简单,
只需在Activity中调用以下代码: Java代码
1. int screenWidth;//屏幕宽度
2. int screenHeight;//屏幕高度
3. WindowManager windowManager = getWindowManager();
4. Display display = windowManager.getDefaultDisplay();
5.
6. screenWidth = display.getWidth();
7. screenHeight = display.getHeight();
8.