Kenny Freeman Kenny Freeman - 3 months ago 12
Java Question

ImageButton crashes App with GridView

Hey guys I'm trying to add an ImageButton over a GridView for an android app. The app runs fine until I add the ImageButton. Here is the logCatenter image description here

Here is my XML

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/calendar"
android:src="@drawable/android_calendar"
android:layout_marginRight="120dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />

</RelativeLayout>

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="120dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth">
</GridView>

</RelativeLayout>


Here is the Java File.

package com.yourname.photogallery;

import java.util.ArrayList;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.SearchManager;
import android.app.SearchableInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SearchView;

public class PhotoGalleryFragment extends VisibleFragment {
private static final String TAG = "PhotoGalleryFragment";
GridView mGridView;
ArrayList<GalleryItem> mItems;
ThumbnailDownloader<ImageView> mThumbnailThread;

private ImageButton calendarButt;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setRetainInstance(true);
setHasOptionsMenu(true);

updateItems();

calendarButt = (ImageButton) mGridView.findViewById(R.id.calendar);
calendarButt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

}
});

//mThumbnailThread = new ThumbnailDownloader<ImageView>();
mThumbnailThread = new ThumbnailDownloader<ImageView>(new Handler());
mThumbnailThread.setListener(new ThumbnailDownloader.Listener<ImageView>(){
public void onThumbnailDownloaded(ImageView imageView, Bitmap thumbnail) {
if (isVisible()) {
imageView.setImageBitmap(thumbnail);
}
}
});

mThumbnailThread.start();
mThumbnailThread.getLooper();
Log.i(TAG, "Background thread started");
}
public void updateItems() {
new FetchItemsTask().execute();
}



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_photo_gallery, container, false);


mGridView = (GridView)v.findViewById(R.id.gridView);

setupAdapter();

mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> gridView, View view, int pos,
long id) {
GalleryItem item = mItems.get(pos);

Uri photoPageUri = Uri.parse(item.getPhotoPageUrl());
Intent i = new Intent(getActivity(), PhotoPageActivity.class);
i.setData(photoPageUri);

startActivity(i);
}
});

return v;
}

@Override
public void onDestroyView() {
super.onDestroyView();
mThumbnailThread.clearQueue();
}

@Override
@TargetApi(11)
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_photo_gallery, menu);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
//pull out the SearchView
MenuItem searchItem = menu.findItem(R.id.menu_item_search);
SearchView searchView = (SearchView)searchItem.getActionView();

//Get the data from out searchable.xml as a Searchable
SearchManager searchManager = (SearchManager)getActivity()
.getSystemService(Context.SEARCH_SERVICE);
ComponentName name = getActivity().getComponentName();
SearchableInfo searchInfo = searchManager.getSearchableInfo(name);
searchView.setSearchableInfo(searchInfo);
}
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_search:
getActivity().onSearchRequested();
return true;
case R.id.menu_item_clear:
PreferenceManager.getDefaultSharedPreferences(getActivity())
.edit()
.putString(FlickrFetchr.PREF_SEARCH_QUERY, null)
.commit();
updateItems();
return true;
case R.id.menu_item_toggle_polling:
boolean shouldStartAlarm = !PollService.isServiceAlarmOn(getActivity());
PollService.setServiceAlarm(getActivity(), shouldStartAlarm);

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
getActivity().invalidateOptionsMenu();

return true;
default:
return super.onOptionsItemSelected(item);
}
}

@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);

MenuItem toggleItem = menu.findItem(R.id.menu_item_toggle_polling);
if(PollService.isServiceAlarmOn(getActivity())) {
toggleItem.setTitle(R.string.start_polling);
}
}

@Override
public void onDestroy() {
super.onDestroy();
mThumbnailThread.quit();
Log.i(TAG, "Background thread destroyed");
}



void setupAdapter() {
if (getActivity() == null || mGridView == null) return;

if (mItems !=null) {
//mGridView.setAdapter(new ArrayAdapter<GalleryItem>(getActivity(), android.R.layout.simple_gallery_item, mItems));
mGridView.setAdapter(new GalleryItemAdapter(mItems));
}
else {
mGridView.setAdapter(null);
}
}



private class FetchItemsTask extends AsyncTask<Void, Void, ArrayList<GalleryItem>>{
//private class FetchItemsTask extends AsyncTask<Void, Void, Void> {
@Override
protected ArrayList<GalleryItem> doInBackground(Void... params) {
//protected Void doInBackground(Void... params) {
/*try {
String result = new FlickrFetchr().getUrl("http://www.google.com");
Log.i(TAG, "Fetched contents of URL: " + result);
}
catch (IOException ioe) {
Log.e(TAG, "Failed to fetch URL: ", ioe);
}*/
/*new FlickrFetchr().fetchItems();
return null;*/
//String query = "android"; //Just for testing
Activity activity = getActivity();
if(activity==null)
return new ArrayList<GalleryItem>();

String query = PreferenceManager.getDefaultSharedPreferences(activity)
.getString(FlickrFetchr.PREF_SEARCH_QUERY, null);
if(query != null) {
return new FlickrFetchr().search(query);
}
else {
return new FlickrFetchr().fetchItems();
}

}
@Override
protected void onPostExecute(ArrayList<GalleryItem> items) {
mItems = items;
setupAdapter();
}
}
private class GalleryItemAdapter extends ArrayAdapter<GalleryItem> {
public GalleryItemAdapter (ArrayList<GalleryItem> items) {
super(getActivity(), 0, items);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getActivity().getLayoutInflater()
.inflate(R.layout.gallery_item, parent, false);
}
ImageView imageView = (ImageView)convertView
.findViewById(R.id.gallery_item_imageView);
imageView.setImageResource(R.drawable.brian_up_close);
GalleryItem item = getItem(position);
mThumbnailThread.queueThumbnail(imageView, item.getUrl());

return convertView;
}
}
}


I'm guessing it's something to do with the gridView.findViewById. If I take off gridView and just use findViewById I get error can't resolve and its looking for an int arg. Thanks in advance.

TWL TWL
Answer

calendarButt = (ImageButton) mGridView.findViewById(R.id.calendar)

  1. mGridView may not be ready at this point

  2. R.id.calendar is not a child of your gridview.

  3. You should be using your layout's v for your calender imagebutton, move it to onCreateView. calendarButt = (ImageButton) v.findViewById(R.id.calendar)

Comments