Android:ImageView
来源:互联网 发布:js防止ajax重复提交 编辑:程序博客网 时间:2024/05/18 01:39
ImageView
ImageView,图像视图,直接继承自View类,它的主要功能是用于显示图片,实际上它不仅仅可以用来显示图片,任何Drawable对象都可以使用ImageView来显示。ImageView可以适用于任何布局中,并且Android为其提供了缩放和着色的一些操作。
ImageView的一些常用属性,并且这些属性都有与之对应的getter、setter方法:
- android:adjustViewBounds:设置ImageView是否调整自己的边界来保持所显示图片的长宽比。
- android:maxHeight:设置ImageView的最大高度。
- android:maxWidth:设置ImageView的最大宽度。
- android:scaleType:设置所显示的图片如何缩放或移动以适应ImageView的大小。
- android:src:设置ImageView所显示的Drawable对象的ID。
对于android:scaleType属性,因为关于图像在ImageView中的显示效果,所以有如下属性值可以选择:
- matrix:使用matrix方式进行缩放。
- fitXY:横向、纵向独立缩放,以适应该ImageView。
- fitStart:保持纵横比缩放图片,并且将图片放在ImageView的左上角。
- fitCenter:保持纵横比缩放图片,缩放完成后将图片放在ImageView的中央。
- fitEnd:保持纵横比缩放图片,缩放完成后将图片放在ImageView的右下角。
- center:把图片放在ImageView的中央,但是不进行任何缩放。
- centerCrop:保持纵横比缩放图片,以使图片能完全覆盖ImageView。
- centerInside:保持纵横比缩放图片,以使得ImageView能完全显示该图片。
图片基本显示
下面通过一个示例效果,来说明一下ImageView是如何显示图片的,再此示例中,需要使用到一个green.png的图片,需要放到drawable文件夹下,关于Android的资源文件,以后再进行详解。
布局代码:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="scaleType:center,未缩放,在ImageView的中心" /> <ImageView android:id="@+id/imageview1" android:layout_width="200dp" android:layout_height="100dp" android:background="#F00" android:scaleType="center" android:src="@drawable/green" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="scaleType:fitCenter,按比例缩放" /> <ImageView android:id="@+id/imageview2" android:layout_width="300dp" android:layout_height="200dp" android:background="#FFF" android:padding="10dp" android:scaleType="fitCenter" android:src="@drawable/green" /></LinearLayout>
以下设定图片大小
android:layout_width=”300dp”
android:layout_height=”200dp”
效果展示:
缩放与旋转图片
因为ImageView继承自View,所以在代码中设置其大小,可以使用View.setLayoutParams(new LinearLayout.LayoutParams(newWidth,newHeight))方法,这个方法可以直接设定View下的所有控件的外观大小,所以这里也适用于ImageView。
要是RelativeLayout就要相应地使用View.setLayoutParams(new RelativeLayout.LayoutParams(newWidth,newHeight)); 这样设置其大小属性。
而对于ImageView的旋转,这里涉及到一个Matrix类的使用。它表示一个3x3的坐标变换矩阵,可以在这个矩阵内,对其进行变换、旋转操作,它需要通过构造函数显式的初始化之后才可以使用。
下面通过一个示例来说明一下图片的放大缩小与旋转的示例,在示例中会提供两个SeekBar,对于SeekBar如果不了解的话,可以参见我的另外一篇博客,Android—UI之Progress。这两个SeekBar一个设置ImageView显示图片的大小,另一个设置旋转的角度。对于图片大小,通过DisplayMetrics设置屏幕的宽度为图像的最大宽度,具体操作在注释中已经写明,这里不在累述。
布局代码:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/imageview3" android:layout_width="200dp" android:layout_height="150dp" android:scaleType="fitCenter" android:src="@drawable/green" /> <TextView android:id="@+id/tv1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="图像宽度:240 图像高度:150" /> <SeekBar android:id="@+id/sbSize" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:max="240" android:progress="120" /> <TextView android:id="@+id/tv2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="0°" /> <SeekBar android:id="@+id/sbRotate" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:max="360" /></LinearLayout>
实现代码:
package com.bgxt.imageviewdemo;import android.annotation.SuppressLint;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.graphics.drawable.BitmapDrawable;import android.os.Bundle;import android.util.DisplayMetrics;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;import android.widget.TextView;@SuppressLint("NewApi")public class ChangeImageActivity extends Activity implements OnSeekBarChangeListener { private int minWidth = 80; private ImageView imageView; private TextView textview1, textview2; Matrix matrix=new Matrix(); @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.layout_changeimage); imageView = (ImageView) findViewById(R.id.imageview3); SeekBar seekbar1 = (SeekBar) findViewById(R.id.sbSize); SeekBar seekbar2 = (SeekBar) findViewById(R.id.sbRotate); textview1 = (TextView) findViewById(R.id.tv1); textview2 = (TextView) findViewById(R.id.tv2); //获取当前屏幕的尺寸,并设置图片放大的最大尺寸,不能超过屏幕尺寸 DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); seekbar1.setMax(dm.widthPixels - minWidth); seekbar1.setOnSeekBarChangeListener(this); seekbar2.setOnSeekBarChangeListener(this); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (seekBar.getId() == R.id.sbSize) { //设置图片的大小 int newWidth=progress+minWidth; int newHeight=(int)(newWidth*3/4); imageView.setLayoutParams(new LinearLayout.LayoutParams(newWidth, newHeight)); textview1.setText("图像宽度:"+newWidth+"图像高度:"+newHeight); } else if (seekBar.getId() == R.id.sbRotate){ //获取当前待旋转的图片 Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.green); //设置旋转角度 matrix.setRotate(progress,30,60); //通过待旋转的图片和角度生成新的图片 bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true); //绑定图片到控件上 imageView.setImageBitmap(bitmap); textview2.setText(progress+"°"); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } @Override public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub }}
效果展示:
从互联网获取图片
一个移动的平台开发,很多资源是不可能一直保存在本地的,更多实时性的东西,是需要直接通过网络及时获取的。这里通过一个从网上获取图片展示到ImageView的例子,来讲解一下这个功能的实现。
在Android4.0之后,增加了一些新特性,也增加了一些限制。其中有一个限制就是不能在主线程中访问网络,必须另开一条线程访问。但是这里又存在另外一个问题,在子线程中,无法直接操作UI控件的属性。如果你们使用的开发平台是Android4.0之下,就不存在这个问题,直接在主线程中访问网络操作UI控件即可。
我的解决方案就是,通过Thread类,进行多线程访问网络,再通过Handler类,进行消息传递。对于Thread类,是Java的知识,不再详细讲解,对于Handler类,这里简要说明一下。
在Android平台下,不允许Activity新启动的线程访问该Activity里的界面UI控件,这样就会导致新启动的线程无法动态改变界面UI控件的属性值。所以就需要借助Handler的消息传递机制来实现。Handler类的主要作用有两个:
- 在新启动的线程中发送消息。
在主线程中获取、处理消息。
上面描述的两个作用,发送消息好说,在需要的时候发送,那怎么确定什么时候接收消息呢?为了让主线程能接受并处理新启动的线程发送的消息,Android通过回调的方式来实现,开发人员只需要重写Handler类中处理消息的方法,handleMessage(Message)即可,其中Message封装了发送过来的消息。
Handler包含如下方法,用于实现发送和处理消息:
void handleMessage(Message msg):处理消息的方法,用于被重写。
- final boolean hasMessage(int what):检查消息队列中是否包含what属性为指定值的消息。
- sendEmptyMessage(int what):立即发送空消息。
- final boolean sendEmptyMessageDelayed(int what,long delayMillis):指定delayMillis毫秒之后发送空消息。
- final boolean sendMessage(Message msg):立即发送消息。
final boolean sendMessageDelayed(Message msg,long delayMillis):指定delayMillis毫秒之后发送消息。
Message封装了线程中传递的消息,如果对于一般的数据,Message提供了getData()和setData()方法来获取与设置数据,其中操作的数据是一个Bundle对象,这个Bundle对象提供一系列的getXxx()和setXxx()方法用于传递基本数据类型,对于基本数据类型,使用起来很简单,这里不再详细讲解。而对于复杂的数据类型,如一个对象的传递就要相对复杂一些。在Bundle中提供了两个方法,专门用来传递对象的,但是这两个方法也有相应的限制,需要实现特定的接口,当然,一些Android自带的类,其实已经实现了这两个接口中的某一个,可以直接使用。方法如下:
- putParcelable(String key,Parcelable value):需要传递的对象类实现Parcelable接口。
- pubSerializable(String key,Serializable value):需要传递的对象类实现Serializable接口。
还有另外一种方式在Message中传递对象,那就是使用Message自带的obj属性传值,它是一个Object类型,所以可以传递任意类型的对象,Message自带的有如下几个属性:
- int arg1:参数一,用于传递不复杂的数据,复杂数据使用setData()传递。
- int arg2:参数二,用于传递不复杂的数据,复杂数据使用setData()传递。
- Object obj:传递一个任意的对象。
int what:定义的消息码,一般用于确定消息的来源。
下面这个示例,使用了两种方式获取传递消息,以一个随机数确定。在这个示例中,访问网络的代码会附上但是不会详解,如果对于Android中访问网络不熟悉的朋友,可以参见我另外一篇博客,Android–Http协议。
布局代码:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/btnInternet" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下载网络图片"/> <TextView android:id="@+id/tbMsgType" android:layout_width="match_parent" android:layout_height="wrap_content"/> <ImageView android:id="@+id/ivInternet" android:layout_width="wrap_content" android:layout_height="wrap_content"/></LinearLayout>
实现代码:
package com.bgxt.imageviewdemo;import java.io.InputStream;import java.net.HttpURLConnection;import java.util.Random;import com.bgxt.httputils.HttpUtils;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;public class InternetImageActivity extends Activity { private Button btnInternet; private ImageView ivInternet; private TextView tvMsgType; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_internetimage); btnInternet = (Button) findViewById(R.id.btnInternet); ivInternet = (ImageView) findViewById(R.id.ivInternet); tvMsgType = (TextView) findViewById(R.id.tbMsgType); // 定义一个handler,用于接收消息 handler = new Handler() { @Override public void handleMessage(Message msg) { Bitmap bmp = null; // 通过消息码确定使用什么方式传递图片信息 if (msg.what == 0) { bmp = (Bitmap) msg.obj; tvMsgType.setText("使用obj传递数据"); } else { Bundle ble = msg.getData(); bmp = (Bitmap) ble.get("bmp"); tvMsgType.setText("使用Bundle传递数据"); } // 设置图片到ImageView中 ivInternet.setImageBitmap(bmp); } }; btnInternet.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //清空之前获取的数据 tvMsgType.setText(""); ivInternet.setImageBitmap(null); //定义一个线程类 new Thread() { @Override public void run() { try { //获取网络图片 InputStream inputStream = HttpUtils .getImageViewInputStream(); Bitmap bitmap = BitmapFactory .decodeStream(inputStream); Message msg = new Message(); Random rd = new Random(); int ird = rd.nextInt(10); //通过一个随机数,随机选择通过什么方式传递图片信息到消息中 if (ird / 2 == 0) { msg.what = 0; msg.obj = bitmap; } else { Bundle bun = new Bundle(); bun.putParcelable("bmp", bitmap); msg.what = 1; msg.setData(bun); } //发送消息 handler.sendMessage(msg); } catch (Exception e) { } } }.start(); } }); }}
访问网络类,代码:
package com.bgxt.httputils;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;public class HttpUtils { private final static String URL_PATH = "http://ww4.sinaimg.cn/bmiddle/9e58dccejw1e6xow22oc6j20c80gyaav.jpg"; public HttpUtils() { } public static InputStream getImageViewInputStream() throws IOException { InputStream inputStream = null; URL url = new URL(URL_PATH); if (url != null) { HttpURLConnection httpURLConnection = (HttpURLConnection) url .openConnection(); httpURLConnection.setConnectTimeout(3000); httpURLConnection.setRequestMethod("GET"); httpURLConnection.setDoInput(true); int response_code = httpURLConnection.getResponseCode(); if (response_code == 200) { inputStream = httpURLConnection.getInputStream(); } } return inputStream; }}
效果展示:
一个error调用栈
12-10 10:38:01.256 2206-2206/com.example E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams at android.widget.RelativeLayout$DependencyGraph.findRoots(RelativeLayout.java:1562) at android.widget.RelativeLayout$DependencyGraph.getSortedViews(RelativeLayout.java:1509) at android.widget.RelativeLayout.sortChildren(RelativeLayout.java:342) at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:363) at android.view.View.measure(View.java:15518) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4825) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:15518) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4825) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404) at android.widget.LinearLayout.measureVertical(LinearLayout.java:695) at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) at android.view.View.measure(View.java:15518) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4825) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2176) at android.view.View.measure(View.java:15518) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1874) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1089) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1265) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) at android.view.Choreographer.doCallbacks(Choreographer.java:562) at android.view.Choreographer.doFrame(Choreographer.java:532) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) at android.os.Handler.handleCallback(Handler.java:725) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5041) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method)
- android-ImageView
- android imageview
- Android ImageView
- android-ImageView
- Android ImageView
- Android-ImageView
- Android-ImageView
- Android ImageView
- Android:ImageView
- Android:ImageView
- Android ImageView
- Android ImageView
- android ImageView
- android 实现圆形imageView,Circle imageView
- android控件之imageview 以及重写imageview
- ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType)
- ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType)
- ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType)
- Android:Intent
- [AHK]语音识别
- 教辅的组成 洛谷1231 网络流
- 《计算机系统要素》学习笔记:第四章机器语言
- 在指定长度的棍子中找到能组成最大周长三角形的三根棍子
- Android:ImageView
- 7分钟内快速开发一款Oculus Rift虚拟现实游戏
- Android:Content Provider例子
- 九度OJ-1435-迷瘴(HDOJ-2570)
- append和appendTo的区别以及js中的appendChild用法
- 使用Lock,Condition解决三个线程依次轮流打印出75个数
- Android : Gallery使用例子
- 2016,不忘初心;2017,方得始终!
- Android:HttpURLConnection使用,Tomcat的Servlet