javaandroidgridviewandroid-gridviewcoverflow

How to implement coverflow layout from existing gridview images


i am using eclipse. Basically what i am trying to implement is that , that i have a gridView which is fetching images from mysql database dynamically using JSON. Now , instead of gridview i want to show them as coverflow view.

I have searched through the internet , but was not able to find any library or example for dynamic images , i only found for static images stored in the app itself and not on external database.

My code are as follows:-

MainActivity.java:-

public class MainActivity extends Activity implements OnClickListener {
// Log tag
private static final String TAG = MainActivity.class.getSimpleName();

// Movies json url
private static final String url = "http://eventassociate.com/wedding/photomania";
private ProgressDialog pDialog;
private List<Movie> movieList = new ArrayList<Movie>();
private PullToRefreshGridView mPullRefreshGridView;
private GridView gridView;
private CustomListAdapter adapter;
ImageButton blackcapture;
private static int RESULT_LOAD_IMAGE = 1;
String picturePath;

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


    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.gallary_activity_main);

    overridePendingTransition(R.anim.push_down_in, R.anim.push_down_out);




    mPullRefreshGridView = (PullToRefreshGridView) findViewById(R.id.list);
    gridView = mPullRefreshGridView.getRefreshableView();


    mPullRefreshGridView.setOnRefreshListener(new OnRefreshListener2<GridView>() {

        @Override
        public void onPullDownToRefresh(PullToRefreshBase<GridView> refreshView) {


            adapter.notifyDataSetChanged();
            gridView.setAdapter(adapter);
            gridView.invalidateViews();

            mPullRefreshGridView.onRefreshComplete();

        }










    adapter = new CustomListAdapter(this, movieList);
    gridView.setAdapter(adapter);




    gridView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View v,
                int position, long id) {

            Movie m5 = movieList.get(position);

            Intent i = new Intent(getApplicationContext(),
                    FullImageActivity.class);

            i.putExtra("movieobject", m5);
            startActivity(i);


        }
    });

Adapter Class:-

public class CustomListAdapter extends BaseAdapter  {
private Activity activity;


private LayoutInflater inflater;
List<Movie> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();

public CustomListAdapter(Activity activity, List<Movie> movieItems) {
    this.activity = activity;
    this.movieItems = movieItems;
}







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

@Override
public Object getItem(int location) {
    return movieItems.get(location);
}

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

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




    if (inflater == null)
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (convertView == null)
        convertView = inflater.inflate(R.layout.gallary_list_row, null);

    if (imageLoader == null)
        imageLoader = AppController.getInstance().getImageLoader();
    NetworkImageView thumbNail = (NetworkImageView) convertView
            .findViewById(R.id.thumbnail);








    // ...............................................

    TextView title = (TextView) convertView.findViewById(R.id.title);

    // getting movie data for the row
    Movie m = movieItems.get(position);

    // thumbnail image
    thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);

    // title
    title.setText(m.getTitle());







    return convertView;

}

Movie.java:-

public class Movie implements Parcelable{
private String title,thumbnailUrl;



public Movie() {
    // TODO Auto-generated constructor stub
}

public Movie(String name, String thumbnailUrl
        ) {
    this.title = name;
    this.thumbnailUrl = thumbnailUrl;

}



public String getTitle() {
    return title;
}

public void setTitle(String name) {
    this.title = name;
}

public String getThumbnailUrl() {
    return thumbnailUrl;
}

public void setThumbnailUrl(String thumbnailUrl) {
    this.thumbnailUrl = "http://eventassociate.com/wedding/"+thumbnailUrl;
}

 // Parcelling part
public Movie(Parcel in){
    String[] data = new String[2];

    in.readStringArray(data);
    this.title = data[0];
    this.thumbnailUrl = data[1];

}








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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeStringArray(new String[] {this.title,
                                        this.thumbnailUrl,
                                        });
}


 public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
     public Movie createFromParcel(Parcel in) {
         return new Movie(in); 
     }

     public Movie[] newArray(int size) {
         return new Movie[size];
     }
 };

}

I successfully implemented this as GridView , but i am facing trouble in implementing this as coverflow design or something like that. I searched on the net and i find this code , but only for static images:-

public class SimpleExample extends Activity {

// =============================================================================
// Child views
// =============================================================================

private FancyCoverFlow fancyCoverFlow;

// =============================================================================
// Supertype overrides
// =============================================================================

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

    this.fancyCoverFlow = (FancyCoverFlow) this.findViewById(R.id.fancyCoverFlow);

    this.fancyCoverFlow.setAdapter(new FancyCoverFlowSampleAdapter());
    this.fancyCoverFlow.setUnselectedAlpha(1.0f);
    this.fancyCoverFlow.setUnselectedSaturation(0.0f);
    this.fancyCoverFlow.setUnselectedScale(0.5f);
    this.fancyCoverFlow.setSpacing(50);
    this.fancyCoverFlow.setMaxRotation(0);
    this.fancyCoverFlow.setScaleDownGravity(0.2f);
    this.fancyCoverFlow.setActionDistance(FancyCoverFlow.ACTION_DISTANCE_AUTO);

}

// =============================================================================
// Private classes
// =============================================================================

}

Adapter.java:-

public class FancyCoverFlowSampleAdapter extends FancyCoverFlowAdapter {

// =============================================================================
// Private members
// =============================================================================

private int[] images = {R.drawable.image1, R.drawable.image2, R.drawable.image3, R.drawable.image4, R.drawable.image5, R.drawable.image6,};

// =============================================================================
// Supertype overrides
// =============================================================================

@Override
public int getCount() {
    return images.length;
}

@Override
public Integer getItem(int i) {
    return images[i];
}

@Override
public long getItemId(int i) {
    return i;
}

@Override
public View getCoverFlowItem(int i, View reuseableView, ViewGroup viewGroup) {
    ImageView imageView = null;

    if (reuseableView != null) {
        imageView = (ImageView) reuseableView;
    } else {
        imageView = new ImageView(viewGroup.getContext());
        imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
        imageView.setLayoutParams(new FancyCoverFlow.LayoutParams(300, 400));

    }

    imageView.setImageResource(this.getItem(i));
    return imageView;
}

}

Can someone help me , in solving my problem. Thanks.

My final code with coverflow:-

MainActivity:-

public class MainActivity extends Activity implements OnClickListener {
// Log tag
private static final String TAG = album.MainActivity.class.getSimpleName();

// Movies json url
private static final String url = "http://eventassociate.com/wedding/androidadminimages";
private ProgressDialog pDialog;
private List<Moviealbum> movieList = new ArrayList<Moviealbum>();

private FancyCoverFlow fancyCoverFlow;


private CustomListAdapter adapter;


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



    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN);



    setContentView(R.layout.album_activity_main);

    overridePendingTransition(R.anim.push_down_in, R.anim.push_down_out);

    this.fancyCoverFlow = (FancyCoverFlow) this.findViewById(R.id.list);

    adapter = new CustomListAdapter(this, movieList);

    this.fancyCoverFlow.setAdapter(new CustomListAdapter(this, movieList));
    this.fancyCoverFlow.setUnselectedAlpha(1.0f);
    this.fancyCoverFlow.setUnselectedSaturation(0.0f);
    this.fancyCoverFlow.setUnselectedScale(0.5f);
    this.fancyCoverFlow.setSpacing(50);
    this.fancyCoverFlow.setMaxRotation(0);
    this.fancyCoverFlow.setScaleDownGravity(0.2f);
    this.fancyCoverFlow.setActionDistance(FancyCoverFlow.ACTION_DISTANCE_AUTO);














    fancyCoverFlow.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View v,
                int position, long id) {

            Moviealbum m5 = movieList.get(position);

            Intent i = new Intent(getApplicationContext(),album.
                    FullImageActivity.class);

            i.putExtra("movieobject", m5);
            startActivity(i);


        }
    });











    pDialog = new ProgressDialog(this);
    // Showing progress dialog before making http request
    pDialog.setMessage("Loading...");
    pDialog.show();

    // changing action bar color
    getActionBar().setBackgroundDrawable(
            new ColorDrawable(Color.parseColor("#1b1b1b")));

    // Creating volley request obj
    JsonArrayRequest movieReq = new JsonArrayRequest(url,
            new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    Log.d(TAG, response.toString());
                    hidePDialog();

                    // Parsing json
                    for (int i = 0; i < response.length(); i++) {
                        try {

                            JSONObject obj = response.getJSONObject(i);
                            Moviealbum movie = new Moviealbum();
                            movie.setTitle(obj.getString("no"));
                            movie.setThumbnailUrl(obj.getString("alinks"));

                            // adding movie to movies array
                            movieList.add(movie);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }

                    // notifying list adapter about data changes
                    // so that it renders the list view with updated data
                    adapter.notifyDataSetChanged();
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    VolleyLog.d(TAG, "Error: " + error.getMessage());
                    hidePDialog();

                }
            });

    // Adding request to request queue...................................
    AppController.getInstance().addToRequestQueue(movieReq);
}

@Override
public void onDestroy() {
    super.onDestroy();
    hidePDialog();
}

private void hidePDialog() {
    if (pDialog != null) {
        pDialog.dismiss();
        pDialog = null;
    }
}

AdapterClass :-

public class CustomListAdapter extends  FancyCoverFlowAdapter  {
private Activity activity;


private LayoutInflater inflater;
List<Moviealbum> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();

public CustomListAdapter(Activity activity, List<Moviealbum> movieItems) {
    this.activity = activity;
    this.movieItems = movieItems;
}







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

@Override
public Object getItem(int location) {
    return movieItems.get(location);
}

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

 @Override
    public View getCoverFlowItem(int position, View reuseableView, ViewGroup viewGroup) {




    if (inflater == null)
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (reuseableView == null)
        reuseableView = inflater.inflate(R.layout.gallary_list_row, null);

    if (imageLoader == null)
        imageLoader = AppController.getInstance().getImageLoader();
    NetworkImageView thumbNail = (NetworkImageView) reuseableView
            .findViewById(R.id.thumbnail);











    // ...............................................

    TextView title = (TextView) reuseableView.findViewById(R.id.title);

    // getting movie data for the row
    Moviealbum m = movieItems.get(position);

    // thumbnail image
    thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);

    // title
    title.setText(m.getTitle());







    return reuseableView;

}

The app runs fine , but after loading blank screen is shown with no images.

Logcat:-

enter image description here


Solution

  • Your issue isn't with the CoverFlow code, but rather where you're doing your network operation. On app load, begin your network request for your JSON payload, show a spinner to show the app is loading, and populate your Adapter once your images are loaded. I'm assuming you have network code already given your GridView implementation? Let me know if I've missed something. I hope that helps!

    EDIT:

    Once you've added images to your Adapter make sure you call notifyDataSetChanged() to tell your adapter to reload its views.

    EDIT 2:

    Look at this line here: this.fancyCoverFlow.setAdapter(new CustomListAdapter(this, movieList));

    You're passing a new CustomListAdapter rather than passing in your adapter variable. Try fixing that and let me know if it works.