开发者

Android Gallery with first thumbnail as coverpage

Thanks for reading!

Some background:

I am building a Gallery app from the tutorial here

Only change I made to this code is to replace

i.setLayoutParams(new Gallery.LayoutParams(150, 100));

with

i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

to display only one gallery image at a time (Kinda like a slideshow viewer).

Problem:

I want the first thumbnail of the gallery to act as an Album Cover with two TextView's to display Album info.

Experiment: So, I created an cover.xml like this:

 
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:padding="6dip">
    <ImageView android:id="@+cover/imgImage" android:adjustViewBounds="true"
        android:layout_width="fill_parent" android:layout_height="fill_parent">
    </ImageView>
    <TextView android:id="@+cover/tvCoverText1"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:maxLines="2" android:text="Text1" />
    <TextView android:id="@+cover/tvCoverText2"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:singleLine="true" android:maxLines="1" android:layout_below="@cover/tvCoverText1"
        android:text="Text2" />
</RelativeLayout>

And here's the Java code. I check in getView() if the position is 0 (the first thumbnail) and then play around with the views.


package com.sagar.sample;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android开发者_如何学运维.widget.Gallery;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends Activity {

    private LayoutInflater mInflater = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Gallery g = (Gallery) findViewById(R.main.gallery);
        g.setAdapter(new ImageAdapter(this));

        g.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView parent, View v, int position, long id) {
                Toast.makeText(Main.this, "" + position, Toast.LENGTH_SHORT).show();
            }
        });
    }

    public class ImageAdapter extends BaseAdapter {
        int mGalleryItemBackground;
        private Context mContext;

        private Integer[] mImageIds = {
                0, R.drawable.bp1, R.drawable.bp2, R.drawable.bp3 
        };

        public ImageAdapter(Context c) {
            mContext = c;
            mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//            TypedArray a = obtainStyledAttributes(R.styleable.HelloGallery);
//            mGalleryItemBackground = a.getResourceId(
//                    R.styleable.HelloGallery_android_galleryItemBackground, 0);
//            a.recycle();
        }

        public int getCount() {
            return mImageIds.length;
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            View view = convertView;
            if(view == null) {
                view = mInflater.inflate(R.layout.cover, null);

                viewHolder = new ViewHolder();
                viewHolder.tvCoverText1 = (TextView)view.findViewById(R.cover.tvCoverText1);
                viewHolder.tvCoverText2 = (TextView)view.findViewById(R.cover.tvCoverText2);
                viewHolder.imgView = (ImageView)view.findViewById(R.cover.imgImage);
                view.setTag(viewHolder);             
            }
            else {
                viewHolder = (ViewHolder)view.getTag();
            }

            if(position == 0) {
                viewHolder.tvCoverText1.setVisibility(View.VISIBLE);
                viewHolder.tvCoverText2.setVisibility(View.VISIBLE);
                viewHolder.imgView.setVisibility(View.GONE);
            }
            else {
                viewHolder.tvCoverText1.setVisibility(View.GONE);
                viewHolder.tvCoverText2.setVisibility(View.GONE);
                viewHolder.imgView.setVisibility(View.VISIBLE);
                //viewHolder.imgView = new ImageView(mContext);
                viewHolder.imgView.setImageResource(mImageIds[position]); //Album cover is at 0th position
                viewHolder.imgView.setLayoutParams(new Gallery.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
                viewHolder.imgView.setScaleType(ImageView.ScaleType.FIT_XY);
                viewHolder.imgView.setBackgroundResource(mGalleryItemBackground);
            }
            return view;
        }
    }

    static class ViewHolder {
        TextView tvCoverText1, tvCoverText2;
        ImageView imgView;
    }
}

End Result: When the app loads up, I first see a blank screen for a while and then the view changes to display the AlbumCover. And it's painfully slow to scroll across the images.

Hmm..obviously, I am doing something wrong. I sincerely hope someone could help me here :(

Thanks!

UPDATE: Adding main.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <Gallery
        android:id="@+main/gallery"
        android:layout_width="fill_parent" android:layout_height="fill_parent"
    />
</RelativeLayout>

UPDATE2: So, here's some psuedo code to explain what I am trying to achieve:


if(position == 0)
    //show toptext and bottomtext from cover.xml
else
    //show tvTitle1 and tvTitle2 (may later include tvTitle3 and tvTitle4) from main.xml

Right now, only the position 0 case works and that too when I swipe to position 1 and swipe back to position 0 - the TextViews are grayed out and barely visible. :(


You need to set the text in your textviews everytime and not only when you inflate the view.


You should probably have 1 single layout file which holds the ui components in the gallery. Right now you have 2 TextView components which are independent of the Gallery. Instead, create some layout resource like this: gallery_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
    android:id="@+id/imageView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:adjustViewBounds="true"
    android:background="@android:drawable/picture_frame"
    android:layout_centerInParent="true" />
    <TextView 
        android:id="@+main/tvTitle1" android:text="Title 1"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_above="@+main/tvTitle2">
    </TextView>
    <TextView  
        android:id="@+main/tvTitle2" android:text="Title 2"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" android:layout_alignParentLeft="true">
     </TextView>
</RelativeLayout>

So in your getView:

        View v = convertView;
        if(v == null) {
            LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.gallery_item, null);

            holder = new ViewHolder();
            holder.text1 = (TextView)v.findViewById(R.id.tvTitle1);
            holder.text2 = (TextView)v.findViewById(R.id.tvTitle2);
            holder.imageView = (ImageView)v.findViewById(R.id.imageView);

            v.setTag(holder);
        }
        else
            holder = (ViewHolder)v.getTag();

        if(position == 0) {
          holder.text1.setVisibility(View.VISIBLE);
          holder.text2.setVisibility(View.VISIBLE);
          holder.imageView.setVisibility(View.GONE);
        }
        else {
          holder.text1.setVisibility(View.GONE);
          holder.text2.setVisibility(View.GONE);
          holder.imageView.setVisibility(View.VISIBLE);
        }

        return v;

You may find that there is some strange behavior going on when you scroll through items, so you might have to directly access each UI component rather than using the holder:

((TextView)v.findViewById(R.id.tvTitle1)).setVisibility(View.GONE);, etc

You also may be interested in setting different types of views for getView: http://developer.android.com/reference/android/widget/Adapter.html#getItemViewType(int)


After trying all approaches suggested here, I wasn't able to still get a custom gallery the way I wanted it to. I kept running into ClassCastException. So, here's what worked for me till now. This is just a workaround and incase someone comes up with a better way to design a custom gallery - do post your answer here so I can accept it.

Thanks for helping out!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜