ImageView的堆栈应用
范例说明
在设计此范例之前,必须先准备三张图片(两张外框图、一张内框图),将这三张图片放在res/drawable下面,在此使用的图片为PNG图形文件,而图案大小最好是已经调整成符合手机屏幕大小,或者依据手机的分辨率,动态调整ImageView的大小。稍后的范例将介绍如何调整ImageView的大小,这里就不赘述了。
准备好之后,开始做这个酷炫的专业相框应用程序,在Layout当中创建了两个ImageView,且以绝对坐标的方式“堆栈”在一起,在其下方放上两个按钮(Button),按钮的目的是为了要用来切换图片,创建完成后,要在Button事件里处理置换图片的动作。
程序目的为单击Button1、ImageView1会出现right的图片,单击Button2、ImageView1会出现left的图片,而ImageView2皆为固定不动(文件名叫oa),这个范例并不难,先来看看范例运行结果。
范例程序
src/irdc.ex04_07/EX04_07.java
此程序的关键所在就是getResources()方法,这个方法负责访问Resource ID,无论是访问资源里的图片文件、文字都要用到getResources();在此使用getResources().getDrawable()来载入res/drawable里的图片文件,并将图片放置在ImageView当中。
/* import程序略 */
public class EX04_07 extends Activity
{
/*声明 Button、ImageView对象*/
private ImageView mImageView01;
private ImageView mImageView02;
private Button mButton01;
private Button mButton02;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/*取得 Button、ImageView对象*/
mImageView01 = (ImageView)findViewById(R.id.myImageView1);
mImageView02 = (ImageView)findViewById(R.id.myImageView2);
mButton01 = (Button) findViewById(R.id.myButton1);
mButton02 = (Button) findViewById(R.id.myButton2);
/*设置ImageView背景图*/
mImageView01.setImageDrawable(getResources().
getDrawable(R.drawable.right));
mImageView02.setImageDrawable(getResources().
getDrawable(R.drawable.oa));
/*用OnClickListener事件来启动*/
mButton01.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
/*当启动后,ImageView立刻换背景图*/
mImageView01.setImageDrawable(getResources().
getDrawable(R.drawable.right));
}
});
mButton02.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
mImageView01.setImageDrawable(getResources().
getDrawable(R.drawable.left));
}
});
}
}
res/layout/main.xml
创建两个ImageView,一个为外框、另一个为内框,需注意的是,图片需要做一个排序堆栈顺序,将前景图放在上方(以AbsoluteLayout),将背景图放在前景图的下方,这是最简单的堆栈顺序方法。
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
android:id="@+id/widget34"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<!--创建第一个ImageView (第二层图片)-->
<ImageView
android:id="@+id/myImageView1"
android:layout_width="320px"
android:layout_height="280px"
android:layout_x="0px"
android:layout_y="36px"
/>
<!--创建第二个ImageView (第一层图片)-->
<ImageView
android:id="@+id/myImageView2"
android:layout_width="104px"
android:layout_height="157px"
android:layout_x="101px"
android:layout_y="119px"
/>
<!--创建第一个Button -->
<Button
android:id="@+id/myButton1"
android:layout_width="105px"
android:layout_height="66px"
android:text="pic1"
android:layout_x="9px"
android:layout_y="356px"
/>
<!--创建第二个Button -->
<Button
android:id="@+id/myButton2"
android:layout_width="105px"
android:layout_height="66px"
android:text="pic2"
android:layout_x="179px"
android:layout_y="356px"
/>
</AbsoluteLayout>
扩展学习
学会ImageView之后,在扩展学习里,便可尝试着将两个ImageButton Widget堆栈在一起,如此一来,不但同时具有背景图,还有按钮事件。
<ImageButton
android:id="@+id/myImageButton1"
android:state_focused="true"
android:layout_width="320px"
android:layout_height="280px"
android:layout_x="0px"
android:layout_y="36px"
/>
接着,你不妨自由发挥。ImageButton的使用方法已经介绍过,而堆栈的技巧可参考这个范例程序,两者的差别在于只要单击图片,即可直接做换图的动作,不需要再单击面的Button做更换,需要注意的是图片大小要作调整,不然可能会与ImageButton不相符!
4.10 心爱小宝贝相片集
还记得在第3章“Gallery画廊”范例中,为了简化问题,使用了Android默认的Icon作为Gallery显示的内容吗?现在,将数张PNG图片导入Drawable当中,并于onCreate的同时,载入于Gallery Widget中,试着再添加一个OnItemClick的事件,以取得图片的ID编号来响应用户单击图片时的状态,完成Gallery的高级使用。本范例的另一个重点,就是如何设置Gallery图片的宽高以及放置图片Layout的大小,在此我们改写一个继承自BaseAdapter的ImageAdapter容器来存放图片,通过ImageView.setScaleType()的方法来改变图片的显示,再通过setLayoutParams()方法来改变Layout的宽高。
主程序有两大重点:第一,是ImageAdapter继承BaseAdapter class的未实现方法的重写构造;第二,则是Gallery的OnItemClick()方法与图片及Layout宽高设置。
public class EX04_10 extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/*通过findViewById取得*/
Gallery g = (Gallery) findViewById(R.id.mygallery);
/* 添加一ImageAdapter并设置给Gallery对象 */
g.setAdapter(new ImageAdapter(this));
/* 设置一个itemclickListener并Toast被单击图片的位置 */
g.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick
(AdapterView<?> parent, View v, int position, long id)
{
Toast.makeText
(EX04_10.this, getString(R.string.my_gallery_text_pre)
+ position+ getString(R.string.my_gallery_text_post),
Toast.LENGTH_SHORT).show();
}
});
}
/* 改写BaseAdapter自定义一ImageAdapter class */
public class ImageAdapter extends BaseAdapter
{
/*声明变量*/
int mGalleryItemBackground;
private Context mContext;
/*ImageAdapter的构造器*/
public ImageAdapter(Context c)
{
mContext = c;
/* 使用在res/values/attrs.xml中的<declare-styleable>定义
* 的Gallery属性.*/
TypedArray a = obtainStyledAttributes(R.styleable.Gallery);
/*取得Gallery属性的Index id*/
mGalleryItemBackground = a.getResourceId
(R.styleable.Gallery_android_galleryItemBackground, 0);
/*让对象的styleable属性能够反复使用*/
a.recycle();
}
/* 重写的方法getCount,返回图片数目 */
public int getCount()
{
return myImageIds.length;
}
/* 重写的方法getItemId,返回图像的数组id */
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
/* 重写的方法getView,返回一View对象 */
public View getView
(int position, View convertView, ViewGroup parent)
{
/*产生ImageView对象*/
ImageView i = new ImageView(mContext);
/*设置图片给imageView对象*/
i.setImageResource(myImageIds[position]);
/*重新设置图片的宽高*/
i.setScaleType(ImageView.ScaleType.FIT_XY);
/*重新设置Layout的宽高*/
i.setLayoutParams(new Gallery.LayoutParams(136, 88));
/*设置Gallery背景图*/
i.setBackgroundResource(mGalleryItemBackground);
/*返回imageView对象*/
return i;
}
/*构建一Integer array并取得预加载Drawable的图片id*/
private Integer[ ] myImageIds =
{
R.drawable.photo1,
R.drawable.photo2,
R.drawable.photo3,
R.drawable.photo4,
R.drawable.photo5,
R.drawable.photo6,
};
}
}
res/values/attrs.xml
定义Layout外部Resource的XML文件,用来改变Layout的背景图。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Gallery">
<attr name="android:galleryItemBackground" />
</declare-styleable>
</resources>
扩展学习
在Android:ScaleType中定义了下列常数可供使用,通过“ObjectView.ScaleType常数名称”的方式,就可以改变图片的显示方式,如表4-1所示。
表4-1 各常数名称所代表的值
常 数 名 称 |
值 |
|
常 数 名 称 |
值 |
Matrix |
0 |
fitEnd |
4 |
fitXY |
1 |
center |
5 |
fitStart |
2 |
centerCrop |
6 |
fitCenter |
3 |
centerInside |
7 |
另外,在主程序中,我们使用了下面这一段写法:
TypedArray a = obtainStyledAttributes(R.styleable.Gallery);
这是一个引用自制Layout元素的用法,必须在res/values下面添加一个attrs.xml,并在其中定义<declare-styleable>标签TAG,目的是自定义Layout的背景风格,并且通过TypeArray的特性,让相同的Layout元素可以重复用于每一张图片。
4.16 猜猜红桃A在哪儿 | |
ImageView单击事件与透明度处理
范例说明
现在这个范例就简单的利用Android的ImageView对象来实现一个手机小游戏!
有看过别人赌扑克牌吗?一张小桌子,放上三张牌,红桃A、黑桃2与梅花3,庄家先把三张牌都亮出来,让玩家看清楚红桃A在哪里,之后庄家将牌翻面,并随意变换牌的顺序后,玩家开始下注,猜测红桃A是哪一张?如果猜中了,玩家就赢得两倍的下注金;如果猜错了,下注金就被庄家赢走了!
本范例将制作一个猜牌游戏的简化版,游戏一开始并不直接亮出三张牌,而是翻面洗牌之后直接请玩家来猜猜看红桃A是哪一张,游戏过程绝对公平透明,绝对不会有诈赌的情形发生。
范例中使用TextView、Button及三个ImageView对象,一开始三个ImageView都默认显示扑克牌背面,当用户选择了其中一张牌时,三个ImageView同时翻面,程序并依照选择的对错,在TextView中显示结果,并可通过“再玩一次”的Button来重新开始游戏。
实现本范例前需先准备四张图片:红桃A、黑桃2、梅花3及扑克牌背面,并将这四张图片文件存入/res/drawable/文件夹中。以本范例而言,四张图片文件的路径如下:
/res/drawable/p01.png:红桃A
/res/drawable/p02.png:黑桃2
/res/drawable/p03.png:梅花3
/res/drawable/p04.png:扑克牌背面
当游戏一开始,User便从三张扑克牌当中单击一张,然后程序会一次翻开所有牌面,并将User未选择的牌面以灰暗效果处理,在这个范例练习里,将学习ImageView的onClickListener()事件与设置透明度的技巧。
先设置好布局:
<ImageView android:id="@+id/mImage01" android:layout_width="71px" android:layout_height="96px" android:layout_x="20px" android:layout_y="122px" android:src="@drawable/p04" > </ImageView> <ImageView android:id="@+id/mImage02" android:layout_width="71px" android:layout_height="96px" android:layout_x="126px" android:layout_y="122px" android:src="@drawable/p04" > </ImageView> <ImageView android:id="@+id/mImage03" android:layout_width="71px" android:layout_height="96px" android:layout_x="232px" android:layout_y="122px" android:src="@drawable/p04" > </ImageView> <Button android:id="@+id/mButton" android:layout_width="118px" android:layout_height="wrap_content" android:text="@string/str_button" android:layout_x="100px" android:layout_y="302px" > </Button>
主程序设计如下:
public class ex4_16 extends Activity { /*声明对象变量*/ private ImageView mImageView01; private ImageView mImageView02; private ImageView mImageView03; private Button mButton; private TextView mText; /*声明长度为3的int数组,并将三张牌的id放入 R.drawable.p01:红桃A R.drawable.p02:黑桃2 R.drawable.p03:梅花3 R.drawable.p04:扑克牌背面*/
private static int[] s1=new int[]{R.drawable.p01,R.drawable.p02,R.drawable.p03}; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /*加载main.xml Layout */ setContentView(R.layout.main); /* 取得相关对象 */ mText=(TextView)findViewById(R.id.mText); mImageView01=(ImageView)findViewById(R.id.mImage01); mImageView02=(ImageView)findViewById(R.id.mImage02); mImageView03=(ImageView)findViewById(R.id.mImage03); mButton=(Button)findViewById(R.id.mButton); /* 运行洗牌程序 */ randon(); //见后面程序 /* 替mImageView01添加onClickListener*/ mImageView01.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { /* 三张牌同时翻面,并将未选择的两张牌变透明 */ mImageView01.setImageDrawable(getResources().getDrawable(s1[0])); mImageView02.setImageDrawable(getResources().getDrawable(s1[1])); mImageView03.setImageDrawable(getResources().getDrawable(s1[2])); mImageView02.setAlpha(100); mImageView03.setAlpha(100); /* 依有没有猜对来决定TextView要显示的信息 */ if(s1[0]==R.drawable.p01){ mText.setText("哇!你猜对了喔!!拍拍手!"); } else { mText.setText("你猜错了喔!!要不要再试一次?"); } } }); /* 替mImageView02添加onClickListener*/ mImageView02.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { /* 三张牌同时翻面,并将未选择的两张牌变透明 */ mImageView01.setImageDrawable(getResources().getDrawable(s1[0])); mImageView02.setImageDrawable(getResources().getDrawable(s1[1])); mImageView03.setImageDrawable(getResources().getDrawable(s1[2])); mImageView01.setAlpha(100); mImageView03.setAlpha(100); /* 依有没有猜对来决定TextView要显示的信息 */ if(s1[1]==R.drawable.p01){ mText.setText("哇!你猜对了喔!!拍拍手!"); } else { mText.setText("你猜错了喔!!要不要再试一次?"); } } }); /* 替mImageView03添加onClickListener*/ mImageView03.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { /* 三张牌同时翻面,并将未选择的两张牌变透明 */ mImageView01.setImageDrawable(getResources().getDrawable(s1[0])); mImageView02.setImageDrawable(getResources().getDrawable(s1[1])); mImageView03.setImageDrawable(getResources().getDrawable(s1[2])); mImageView01.setAlpha(100); mImageView02.setAlpha(100); /* 依有没有猜对来决定TextView要显示的信息 */ if(s1[2]==R.drawable.p01){ mText.setText("哇!你猜对了喔!!拍拍手!"); } else { mText.setText("你猜错了喔!!要不要再试一次?"); } } }); /* 单击Button后三张牌都翻为背面且重新洗牌*/ mButton.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { mText.setText("猜猜看红桃A是哪一张?"); mImageView01.setImageDrawable(getResources() .getDrawable(R.drawable.p04)); mImageView02.setImageDrawable(getResources() .getDrawable(R.drawable.p04)); mImageView03.setImageDrawable(getResources() .getDrawable(R.drawable.p04)); mImageView01.setAlpha(255); mImageView02.setAlpha(255); mImageView03.setAlpha(255); randon(); } }); } /*重新洗牌的程序*/ private void randon() { for(int i=0;i<3;i++) { int tmp=s1; int s=(int)(Math.random()*2); s1=s1; s1=tmp; } } }
本范例仅运用ImageView的onClick事件,就实现出一个简单的猜牌小游戏,其中洗牌的randon()方法为众多随机洗牌方式的其中一种,各位也可以尝试用其他的方法来改写。
程序中为了视觉的效果,使用了ImageView的setAlpha(int alpha)方法,将没选到的两张牌设置透明度为100,没选到的牌变透明了,选到的那一张牌自然就突显了出来,其中alpha值255即为没有透明度的意思,所以,才会在“再玩一次”按钮的onClick事件中将三张牌的alpha值都重设为255。
|
|
|
文章评论(0条评论)
登录后参与讨论