原创 Android第八站 众多豪华控件 图片处理

2011-1-27 19:22 8438 7 7 分类: 智能手机

目录

4.7 专业相框设计

ImageView的堆栈应用

4.10 心爱小宝贝相片集

4.16 猜猜红桃A在哪儿

ImageView单击事件与透明度处理

 

4.7 专业相框设计

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条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条