Azurespot
Azurespot

Reputation: 3152

The setOnItemLongClickListener in GridView is not clickable

I have tried all the suggestions I could find on S.O., and I was able to use this exact code successfully on a ListView of mine, but for some reason I can't set a long click listener on my GridView. I log inside the method setupGridViewListener(); and it does not even run, yet I have my method inside onCreateView(). Don't know why it won't work. The alert dialog should pop up once long-clicked, but it doesn't. Method is at bottom of my class.

UPDATE:

I did not mention that my onClickListener does work fine. So I can at least do a single click, and this displays my activity. But, that code is in my adapter, so maybe they should be together in the same class? I am including my adapter and my 2 xmls below.

UPDATE 2 I discovered several things that were worth mentioning, even after I got my code working again. First of all, putting my click listeners into my adapter was a mistake. It slowed things down HUGELY... so much so, I was frantic about finding a way to get things on another thread. But in the end, I did not need to. I realized that I could actually get both of my click listeners into my PhotoTab.java class. This immediately made it faster (back to normal). But another curious thing, the IDE would not let me use OnClickListener, but insisted I go back to OnItemClickListener. So once I changed those back, everything worked again. So the listeners ended up being on my GridView variables, e.g. gridView.setOnItemClickListener(new OnItemClickListener() {} not my ImageView item variables. Perhaps this is what made things faster? There is one GridView, but 24 ImageViews (GridView cells). But that is just a guess. I have updated my code to the current, working code. Except I'm still working on the long click code, so that's not right yet. The dialog alert works though, and each item in the GridView is clickable.

PhotoTab.java

    package org.azurespot.cutecollection.phototab;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.GridView;

import org.azurespot.R;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;

/**
 * Created by mizu on 2/8/15.
 */
public class PhotoTab extends Fragment {

    private GridView gridView;
    File[] files;
    ArrayList<PhotoGridItem> photoList = new ArrayList<>();
    ArrayAdapter<PhotoGridItem> adapter;
    Bitmap bitmap;
    byte[] byteArray = null;
    private String[] allSDCardFiles = null;

    PhotoGridItem photoGridItem;

    public PhotoTab() {
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.photo_tab, container, false);

        // with fragments, make sure you include the rootView when finding id
        gridView = (GridView) v.findViewById(R.id.photo_grid);

        // this null check won't instantiate again if it was already
//        if(adapter == null)
        adapter = new GridViewPhotoAdapter(getActivity(), R.layout.photo_grid_item);

        // Set the Adapter to GridView
        gridView.setAdapter(adapter);

        // load contents of SD card
        loadSDCard();

        // add the default icons remaining, to GridView, if less than 24 files on SD card
        for (int i = 0; i < (24 - allSDCardFiles.length); i++) {
            adapter.add(new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
                    R.drawable.ic_photo_placeholder)));
            adapter.notifyDataSetChanged();
            i++;
        }

        //Convert the bitmap to byte array, so can pass through intent
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        final byte[] byteArray = stream.toByteArray();
        this.byteArray = byteArray;

        setupGridViewListener();

        return v;
    }


    public void loadSDCard() {

        try {
            // gets directory CutePhotos from sd card
            File cutePhotosDir = new File(Environment.getExternalStoragePublicDirectory
                    (Environment.DIRECTORY_PICTURES), "Cute Photos");
            // lists all files in CutePhotos, loads in Files[] array
            files = cutePhotosDir.listFiles();

            for (File singleFile : files) {

                String filePath = singleFile.getAbsolutePath();
                // this method makes size small for the view (to save memory)
                bitmap = decodeImageBitmap(filePath, 270, 270);
                photoGridItem = new PhotoGridItem(bitmap);
                // Check if this is a new bitmap file
                adapter.add(photoGridItem);
                adapter.notifyDataSetChanged();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        // get number of files in Cute Photos directory
        allSDCardFiles =  new String[files.length];

    }



    private void setupGridViewListener(){
        gridView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapter,
                                    View item, int pos, long id) {

                Intent i = new Intent(getActivity(), PhotoViewerActivity.class);
                i.putExtra("photo", byteArray);
                startActivity(i);
            }

        });

        // to delete a photo item
        gridView.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> aView, View item,
                                           final int pos, long id) {

                new AlertDialog.Builder(getActivity())
                        .setTitle("Delete")
                        .setMessage("Delete this cute photo?")
                        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                // delete from ArrayList first
//                                PhotoTab.photoList.remove(position);

                                // get file name then delete it from SD card
                                File cutePhotosDir = new File(Environment.getExternalStoragePublicDirectory
                                        (Environment.DIRECTORY_PICTURES), "CutePhotos/" + photoGridItem);
                                cutePhotosDir.delete();


                                // after each item delete, must refresh load so can delete again
//                                photoTab.loadSDCard();
                            }
                        })
                        .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {

                                // do nothing
                                dialog.cancel();
                            }
                        })
                        .setIcon(android.R.drawable.ic_dialog_alert)
                        .show();

                return true;
            }
        });
    }

    // next 2 methods scale the bitmap image to a better size (so not huge)
    public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            if (width > height) {
                inSampleSize = Math.round((float)height / (float)reqHeight);
            } else {
                inSampleSize = Math.round((float)width / (float)reqWidth);
            }
        }

        return inSampleSize;
    }

    public static Bitmap decodeImageBitmap(String path, int reqWidth, int reqHeight) {


        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        Bitmap bm = BitmapFactory.decodeFile(path, options);

        return bm;
    }
}

GridViewPhotoAdapter

    package org.azurespot.cutecollection.phototab;

/**
* Created by mizu on 2/5/15.
*/
// package org.azurespot.cutecollection;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;

import org.azurespot.R;

/**
 * Created by mizu on 2/5/15.
 */
public class GridViewPhotoAdapter extends ArrayAdapter<PhotoGridItem> {

    public Context context;
    private int resourceId;
    ViewHolder holder = null;
    int position;

    public GridViewPhotoAdapter(Context context, int layoutResourceId) {
        super(context, layoutResourceId);
        this.context = context;
        this.resourceId = layoutResourceId;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        View row = convertView;
        this.position = position;

        if (row == null) {

            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(resourceId, parent, false);

            holder = new ViewHolder();
            holder.imageView = (ImageView) row.findViewById(R.id.photo_grid_view);
            // stores holder with view
            row.setTag(holder);

        } else {

            holder = (ViewHolder)row.getTag();
        }

        // gets position of whichever photo you click on in the GridView
        final PhotoGridItem photoGridItem = getItem(position);

        if (photoGridItem != null) {
            Bitmap bm = photoGridItem.getImage();
            holder.imageView.setImageBitmap(bm);

            // positioning the image in the GridView slot
            holder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            holder.imageView.setLayoutParams(new LinearLayout.LayoutParams(270, 270));
        }


        return row;

    }

    public class ViewHolder{
        ImageView imageView;
    }

}

photo_tab.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_view"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#2198bb">

    <GridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/photo_grid"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:verticalSpacing="5dp"
        android:horizontalSpacing="2dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="25dp"
        android:columnWidth="100dp"
        android:gravity="center"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:scrollbarStyle="outsideOverlay"
        android:verticalScrollbarPosition="right" />

</RelativeLayout>

photo_grid_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/photo_grid_view"
        android:focusable="false"
        android:focusableInTouchMode="false"/>
</LinearLayout>

Upvotes: 0

Views: 1866

Answers (3)

A B
A B

Reputation: 338

It would be better to either use click and long click for the imageview, or both on the gridview item.

If you want on imageview, do not setup the GridViewListener and try this in your adapter:

holder.imageView.setOnLongClickListener(new View.OnLongClickListener() {

    @Override
    public boolean onLongClick(View v) {
                    //your code
        return true;
    }
});

holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent i = new Intent(context, PhotoViewerActivity.class);
                i.putExtra("photo", byteArray);
                context.startActivity(i);
            }

        });

Upvotes: 1

user3906057
user3906057

Reputation:

package com.example.slideanim;

import java.util.ArrayList;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.Toast;

public class MyGridAdapter extends BaseAdapter {
    private ArrayList<String> list = new ArrayList<String>();
    private Activity activity;
    private LayoutInflater layoutInflater;

    public MyGridAdapter(Activity activity, ArrayList<String> list) {
        // TODO Auto-generated constructor stub
        this.activity = activity;
        this.list = list;
        layoutInflater = activity.getLayoutInflater();
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return list.size();
    }

    @Override
    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return list.get(arg0);
    }

    @Override
    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int pos, View convertView, ViewGroup arg2) {
        // TODO Auto-generated method stub
        ViewHolder holder = null;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = layoutInflater.inflate(R.layout.row, null);
            holder.imageView = (ImageView) convertView
                    .findViewById(R.id.photo_grid_view);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.imageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });

        holder.imageView.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(activity, "got", Toast.LENGTH_SHORT).show();
                return true;
            }
        });

        return convertView;
    }

    private static class ViewHolder {
        public ImageView imageView;
    }

}

Upvotes: 3

Hardy
Hardy

Reputation: 2606

-First of all check if any Views In your gridview are Focusable or Clickable or not make them False and then check your log again -Let me inform if further issue exist -THanks

Upvotes: 0

Related Questions