Android Open Source - singly-android Friends List Fragment






From Project

Back to project page singly-android.

License

The source code is released under:

MIT License

If you think the Android project singly-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.singly.android.component;
/*  w  w  w . j  a va 2s  .  c  o  m*/
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.JsonNode;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;

import com.singly.android.client.AsyncApiResponseHandler;
import com.singly.android.client.SinglyClient;
import com.singly.android.client.SinglyClient.Authentication;
import com.singly.android.sdk.R;
import com.singly.android.util.JSON;
import com.singly.android.util.RemoteImageCache;

/**
 * A Fragment component that displays a list of friends from all services the
 * user is authenticated against.  This Fragment wraps the Singly /friends API.
 * 
 * The FriendsListFragment uses a number of optimizations to make the list 
 * display quickly and scroll smoothly while supporting lists of any size and 
 * allowing showing an image per friend.  First, an implementation of the 
 * {@link AbstractCachingBlockLoadedListAdapter} is used to load Friend rows in
 * blocks and to cache frequently used rows.  Second {@link RemoteImageCache}
 * is used to download images in background threads while limiting the nummber
 * of concurrent downloads and scaling the images to reduce memory consumption.
 * Third, a view holder pattern is used in the ListAdapter to reuses Views
 * instances in the ListView for smooth scrolling.
 * 
 * The behavior of the FriendsListFragment can be configured as follows:
 * 
 * <ol>
 *   <li>blockSize - The number of Friends loaded in a single block.  The 
 *   maximum is 20 as defined by the /friends API.</li>
 *   <li>blocksToCache - The number of blocks of blockSize to cache.  By default
 *   we cache 50 blocks or 1000 total rows.  Blocks are transparently reloaded
 *   when they are re-requested after being dropped from the cache.</li>
 *   <li>blocksToPreLoad - When a block is loaded, the number of blocks on 
 *   either side to load to support smooth forward and reverse scrolling.</li>
 *   <li>displayImages - True or false, should images be downloaded and
 *   displayed for each Friend in the list.  A default image is displayed if
 *   an image cannot be found or downloaded.</li>
 *   <li>imageCacheSize - The number of images to cache in memory</li>
 *   <li>imageCacheDir - The image cache directory inside app data/files</li>
 *   <li>imagesInParallel - The max images to download in parallel.</li>
 * </ol>
 * 
 * To use the FriendsListFragment you will want to add it to an Activity. The 
 * parent activity can implement {@link FriendsListRowClickListener} to handle 
 * when a given row in the FriendsListFragment is clicked.
 */
public class FriendsListFragment
  extends Fragment {

  protected Activity activity;
  protected LinearLayout friendsLayout;
  protected ListView friendsListView;
  protected FriendsListAdapter friendsListAdapter;
  protected SinglyClient singlyClient;

  // block configuration
  protected int rows = 0;
  protected int blockSize = 20;
  protected int blocksToPreload = 2;
  protected int blocksToCache = 50;

  // image configuration
  protected boolean displayImages = true;
  protected int imageCacheSize = 200;
  protected int imagesInParallel = 2;
  protected String imageCacheDir = null;
  protected RemoteImageCache remoteImageCache;

  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    this.activity = activity;
  }

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

    super.onCreateView(inflater, container, savedInstanceState);

    // create the friends list view
    friendsLayout = (LinearLayout)inflater.inflate(
      R.layout.singly_friends_list_fragment, container, false);
    friendsListView = (ListView)friendsLayout
      .findViewById(R.id.singlyFriendsListView);

    // get the singly client
    this.singlyClient = SinglyClient.getInstance();

    // get the access token and query parameters
    Map<String, String> qparams = new HashMap<String, String>();
    Authentication auth = singlyClient.getAuthentication(activity);
    qparams.put("access_token", auth.accessToken);

    // get total number of rows
    singlyClient.doGetApiRequest(activity, "/friends", qparams,
      new AsyncApiResponseHandler() {

        @Override
        public void onSuccess(String response) {

          // get the number of friends from the friends API
          JsonNode root = JSON.parse(response);
          rows = JSON.getInt(root, "all");

          // create the friends adapter and set into the view
          friendsListAdapter = new FriendsListAdapter(activity, rows,
            blockSize, blocksToPreload, blocksToCache);

          // if showing images, setup the image cache, 2 parallel downloads, 200
          // images in memory
          if (displayImages) {
            remoteImageCache = new RemoteImageCache(activity, imagesInParallel,
              imageCacheDir, imageCacheSize);
            friendsListAdapter.setDisplayImages(true);
            friendsListAdapter.setRemoteImageCache(remoteImageCache);
          }

          friendsListView.setAdapter(friendsListAdapter);

          // handle clicks on friend rows in the friends list view
          friendsListView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View item, int pos,
              long id) {
              if (activity != null
                && activity instanceof FriendsListRowClickListener) {
                Friend friend = friendsListAdapter.getBackingObject(pos);
                ((FriendsListRowClickListener)activity).onFriendClicked(friend,
                  pos);
              }
            }
          });
        }

        @Override
        public void onFailure(Throwable error, String message) {
          Log.e(FriendsListFragment.class.getSimpleName(),
            "Error getting friends", error);
        }
      });

    return friendsLayout;
  }

  @Override
  public void onDestroyView() {
    super.onDestroyView();
    if (remoteImageCache != null) {
      remoteImageCache.shutdown();
    }
  }

  public void setSelection(int position) {
    friendsListView.setSelection(position);
  }

  public int getBlockSize() {
    return blockSize;
  }

  public void setBlockSize(int blockSize) {
    this.blockSize = blockSize;
  }

  public int getBlocksToPreload() {
    return blocksToPreload;
  }

  public void setBlocksToPreload(int blocksToPreload) {
    this.blocksToPreload = blocksToPreload;
  }

  public int getBlocksToCache() {
    return blocksToCache;
  }

  public void setBlocksToCache(int blocksToCache) {
    this.blocksToCache = blocksToCache;
  }

  public boolean isDisplayImages() {
    return displayImages;
  }

  public void setDisplayImages(boolean displayImages) {
    this.displayImages = displayImages;
  }

  public int getImageCacheSize() {
    return imageCacheSize;
  }

  public void setImageCacheSize(int imageCacheSize) {
    this.imageCacheSize = imageCacheSize;
  }

  public int getImagesInParallel() {
    return imagesInParallel;
  }

  public void setImagesInParallel(int imagesInParallel) {
    this.imagesInParallel = imagesInParallel;
  }

  public String getImageCacheDir() {
    return imageCacheDir;
  }

  public void setImageCacheDir(String imageCacheDir) {
    this.imageCacheDir = imageCacheDir;
  }

}




Java Source Code List

com.singly.android.client.AsyncApiResponseHandler.java
com.singly.android.client.AuthenticationActivity.java
com.singly.android.client.AuthenticationWebViewListener.java
com.singly.android.client.BaseAuthenticationWebViewClient.java
com.singly.android.client.FacebookAuthenticationActivity.java
com.singly.android.client.SinglyClient.java
com.singly.android.component.AbstractCachingBlockLoadedListAdapter.java
com.singly.android.component.AuthenticatedServicesActivity.java
com.singly.android.component.AuthenticatedServicesAdapter.java
com.singly.android.component.AuthenticatedServicesFragment.java
com.singly.android.component.DeviceOwnerActivity.java
com.singly.android.component.Friend.java
com.singly.android.component.FriendsListActivity.java
com.singly.android.component.FriendsListAdapter.java
com.singly.android.component.FriendsListFragment.java
com.singly.android.component.FriendsListRowClickListener.java
com.singly.android.component.SinglyService.java
com.singly.android.component.TableOfContentsFragment.java
com.singly.android.component.TableOfContentsTouchListener.java
com.singly.android.examples.MainActivity.java
com.singly.android.util.BitmapUtils.java
com.singly.android.util.ImageCacheListener.java
com.singly.android.util.ImageInfo.java
com.singly.android.util.JSON.java
com.singly.android.util.RemoteImageCache.java
com.singly.android.util.SinglyUtils.java
com.singly.android.util.URLUtils.java