Android Custom Gallery View, Set Own Border

2019-04-02 14:16发布

I have implemented GalleryView. I want to display a border image on selected image from Gallery.

Gallery ga = (Gallery)findViewById(R.id.Gallery01);
    ga.setAdapter(new ImageAdapter(this));//, android.R.layout.simple_list_item_1, items));

    imageView = (ImageView)findViewById(R.id.ImageView01);
    ga.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapter, View view, int location,
                long arg3) {
            imageView.setImageResource(items.get(location));

            final ImageView iv = (ImageView) adapter.getSelectedView();
            iv.setBackgroundResource(R.drawable.large_button_sel_liner);
        }
    });

And my Adapter class

class ImageAdapter1 extends ArrayAdapter<Integer> {

    private Context ctx;
    private List<Integer> items;

    public ImageAdapter1(Context context, int textViewResourceId,
            List<Integer> objects) {
        super(context, textViewResourceId, objects);
        items = objects;
        ctx = context;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ImageView iv = new ImageView(ctx);
        iv.setImageResource(items.get(position));
        iv.setScaleType(ImageView.ScaleType.FIT_XY);
        iv.setLayoutParams(new Gallery.LayoutParams(150,120));

        return iv;
    }
}!

It is totally mashed up. enter image description here

3条回答
Fickle 薄情
2楼-- · 2019-04-02 14:53

What has worked for me in the past is to create an Integer that tracks the click selection, and then apply the background in the getView() method if the position matches the click selection. So (roughly):

Integer selectedLocation = null;

@Override
        public void onItemClick(AdapterView<?> adapter, View view, int location,
                long arg3) {
            selectedLocation = location;
        }

and then in the Adapter View:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ImageView iv = new ImageView(ctx);
    iv.setImageResource(items.get(position));
    iv.setScaleType(ImageView.ScaleType.FIT_XY);
    iv.setLayoutParams(new Gallery.LayoutParams(150,120));
    if(position == selectedLocation){
          iv.setBackgroundResource(R.drawable.large_button_sel_liner);
    }else{
          iv.setBackgroundResource(0);
    }

    return iv;
}

You might have to do a bit more work to track the right selection (the click location and the position might not be the right variables to use), but otherwise something similar should work.

查看更多
Luminary・发光体
3楼-- · 2019-04-02 15:06

Inspired by Nishant Shan's reply, I elaborate my own solution:

First of all, create a border resource: common_galleryborder_shape.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <corners
        android:radius="2dp"
    />
    <solid
        android:color="@android:color/transparent"
    />
    <stroke
        android:width="2dp"
        android:color="@android:color/black"
   />
</shape>

Then create a selector that use this shape: common_gallerycurrentitem_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:state_selected="true"
        android:drawable="@drawable/common_galleryborder_shape"
    />
    <item
        android:drawable="@android:color/transparent"
    />
</selector>

And, finally, add this code to your adapter class:

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView = new ImageView(mContext);

    Integer drawableId = items.get(position);
    Drawable drawable = ctx.getResources().getDrawable(drawableId);
    int width = drawable.getIntrinsicWidth();
    int height = drawable.getIntrinsicHeight();

    imageView.setImageResource(drawableId);
    //sets image size to same size of true image
    imageView.setLayoutParams(new Gallery.LayoutParams(width, height));
    imageView.setScaleType(ImageView.ScaleType.FIT_XY);
    //add a padding for the border
    int padding = dipToPx(mContext, 2);
    imageView.setPadding(padding, padding, padding, padding);
    imageView.setBackgroundResource(R.drawable.common_gallerycurrentitem_selector);

    return imageView;
}

// ----------------------------------------- Private Methods

/**
 * Convert a dimension in dip to px
 * @param context
 * @param dip
 * @return px
 */
private int dipToPx(Context context, int dip) {
    return (int) (dip * context.getResources().getDisplayMetrics().density);
}    

In addition, is also possible set Gallery.setSpacing(int) value to avoid overlapping images inside the gallery.

查看更多
一纸荒年 Trace。
4楼-- · 2019-04-02 15:15

I have got the solution using Selector.

I have created galleryselector.xml

<?xml version="1.0" encoding="utf-8"?>  <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item  android:state_selected="true" 
                    android:drawable="@drawable/large_button_sel_liner"/>
    <item android:drawable="@android:color/transparent" /></selector>

and set it in Adapter class in getView():

imageView.setBackgroundDrawable(getResources().getDrawable(R.drawable.galleryselector));
查看更多
登录 后发表回答