Android Open Source - holoreader R S S Article Adapter






From Project

Back to project page holoreader.

License

The source code is released under:

GNU General Public License

If you think the Android project holoreader 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 de.hdodenhof.holoreader.listadapters;
//from  www  .  java2s .co  m
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.net.URL;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.ColorStateList;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.support.v4.util.LruCache;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import de.hdodenhof.holoreader.R;
import de.hdodenhof.holoreader.misc.DiskLruImageCache;
import de.hdodenhof.holoreader.misc.Helpers;
import de.hdodenhof.holoreader.provider.SQLiteHelper;
import de.hdodenhof.holoreader.provider.SQLiteHelper.ArticleDAO;

/**
 * 
 * @author Henning Dodenhof
 * 
 */
public class RSSArticleAdapter extends SimpleCursorAdapter implements RSSAdapter {

    @SuppressWarnings("unused")
    private static final String TAG = RSSArticleAdapter.class.getSimpleName();

    public static final int MODE_COMPACT = 1;
    public static final int MODE_EXTENDED = 2;

    private static final int LAYOUT_MODE_COMPACT = R.layout.listitem_article;
    private static final int LAYOUT_MODE_EXTENDED = R.layout.listitem_article_extended;
    private static final int ALPHA_STATE_DIMMED = 128;
    private static final int ALPHA_STATE_FULL = 255;

    private LruCache<String, Bitmap> mImageCache;
    private DiskLruImageCache mDiskImageCache;
    private Context mContext;
    private boolean mIsModeExtendedPossible;
    private int mMode;
    private int mLayout;

    public RSSArticleAdapter(Context context, Cursor c, String[] from, int[] to, int flags, int currentMode, boolean isModeExtendedPossible) {
        super(context, (currentMode == MODE_COMPACT) ? LAYOUT_MODE_COMPACT : LAYOUT_MODE_EXTENDED, c, from, to, flags);
        mLayout = (currentMode == MODE_COMPACT) ? LAYOUT_MODE_COMPACT : LAYOUT_MODE_EXTENDED;
        mContext = context;
        mMode = currentMode;
        mIsModeExtendedPossible = isModeExtendedPossible;

        final int memoryClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
        final int cacheSize = 1024 * 1024 * memoryClass / 8;

        mImageCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };

        mDiskImageCache = new DiskLruImageCache(context, "images", cacheSize * 2);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        long id = cursor.getLong(cursor.getColumnIndex(ArticleDAO._ID));
        String title = cursor.getString(cursor.getColumnIndex(ArticleDAO.TITLE));
        String summary = cursor.getString(cursor.getColumnIndex(ArticleDAO.SUMMARY));
        String pubdate = Helpers.formatToYesterdayOrToday(SQLiteHelper.toDate(cursor.getString(cursor.getColumnIndex(ArticleDAO.PUBDATE))));
        String imageURL = cursor.getString(cursor.getColumnIndex(ArticleDAO.IMAGE));
        String read = cursor.getString(cursor.getColumnIndex(ArticleDAO.READ));

        final TextView articleTitle = (TextView) view.findViewById(R.id.list_item_entry_title);
        final TextView articlePubdate = (TextView) view.findViewById(R.id.list_item_entry_date);
        final ImageView articleImage = (ImageView) view.findViewById(R.id.list_item_entry_image);
        final TextView articleSummary = (TextView) view.findViewById(R.id.list_item_entry_summary);

        if (articleTitle != null) {
            articleTitle.setText(title);
        }
        if (articleSummary != null) {
            articleSummary.setText(summary);
        }
        if (articlePubdate != null) {
            articlePubdate.setText(pubdate);
        }

        if (read != null) {
            articleImage.setAlpha(ALPHA_STATE_DIMMED);
            dim(articleTitle);
            dim(articleSummary);
            dim(articlePubdate);
        } else {
            articleImage.setAlpha(ALPHA_STATE_FULL);
            lightup(articleTitle);
            lightup(articleSummary);
            lightup(articlePubdate);
        }

        if (articleImage != null) {
            setInvisible(articleImage);

            if (imageURL != null && imageURL != "") {
                prepareImage(id, imageURL, articleImage);
            }
        }
    }

    @SuppressLint("NewApi")
    private void prepareImage(long id, String imageURL, final ImageView articleImage) {
        try {
            URL url = new URL(imageURL);

            String key = getUniqueKey(id, url);
            Bitmap image = mImageCache.get(key);
            if (image == null) {
                image = mDiskImageCache.getBitmap(key);
            }
            if (image == null) {
                if (cancelPotentialDownload(imageURL, articleImage)) {
                    int imageDimension = (mIsModeExtendedPossible) ? mContext.getResources().getDimensionPixelSize(R.dimen.image_dimension_extended) : mContext
                            .getResources().getDimensionPixelSize(R.dimen.image_dimension_compact);

                    ImageDownloaderTask task = new ImageDownloaderTask(id, articleImage, imageDimension);
                    DownloadDrawable downloadDrawable = new DownloadDrawable(task);
                    articleImage.setImageDrawable(downloadDrawable);

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imageURL);
                    } else {
                        task.execute(imageURL);
                    }
                }
            } else {
                cancelPotentialDownload(imageURL, articleImage);
                articleImage.setImageBitmap(image);
                setVisible(articleImage);
            }
        } catch (MalformedURLException e) {
            // nothing to do here
        }
    }

    private void dim(TextView view) {
        ColorStateList colors = view.getTextColors();
        view.setTextColor(colors.withAlpha(ALPHA_STATE_DIMMED));
    }

    private void lightup(TextView view) {
        ColorStateList colors = view.getTextColors();
        view.setTextColor(colors.withAlpha(ALPHA_STATE_FULL));
    }

    @Override
    public Cursor swapCursor(Cursor c) {
        return super.swapCursor(c);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        final LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(mLayout, parent, false);

        return Helpers.addBackgroundIndicator(context, view, R.attr.customActivatedBackgroundIndicator);
    }

    public int getType() {
        return RSSAdapter.TYPE_ARTICLE;
    }

    public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
        private final WeakReference<ImageView> mImageViewReference;

        private long mID;
        private URL mURL;
        private int mImageDimension;

        public ImageDownloaderTask(long id, ImageView imageView, int imageDimension) {
            mImageViewReference = new WeakReference<ImageView>(imageView);
            mImageDimension = imageDimension;
            mID = id;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            try {
                mURL = new URL(params[0]);
                Bitmap bitmap = BitmapFactory.decodeStream(mURL.openConnection().getInputStream());
                float originalWidth = bitmap.getWidth();
                float originalHeight = bitmap.getHeight();

                if (originalHeight < mImageDimension || originalWidth < mImageDimension) {
                    return null;
                } else {
                    if (originalHeight > mImageDimension) {
                        int newHeight = mImageDimension;
                        int newWidth = (int) ((newHeight / originalHeight) * originalWidth);
                        bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
                    }

                    if (!isCancelled()) {
                        String key = getUniqueKey(mID, mURL);
                        synchronized (mDiskImageCache) {
                            if (mDiskImageCache.getBitmap(key) == null) {
                                mDiskImageCache.put(key, bitmap);
                            }
                        }
                        synchronized (mImageCache) {
                            if (mImageCache.get(key) == null) {
                                mImageCache.put(key, bitmap);
                            }
                        }
                        return bitmap;
                    } else {
                        return null;
                    }
                }

            } catch (IOException e) {
                return null;
            } catch (NullPointerException e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (mImageViewReference != null && bitmap != null) {
                ImageView imageView = mImageViewReference.get();
                ImageDownloaderTask imageDownloaderTask = getImageDownloaderTask(imageView);
                if (this == imageDownloaderTask) {
                    imageView.setImageBitmap(bitmap);
                    setVisible(imageView);
                }
            }
        }
    }

    private void setVisible(View view) {
        view.setVisibility(View.VISIBLE);
        if (mMode == MODE_COMPACT) {
            View articleSummary = ((View) view.getParent()).findViewById(R.id.list_item_entry_summary);
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) articleSummary.getLayoutParams();
            layoutParams.addRule(RelativeLayout.BELOW, R.id.list_item_entry_image);
            articleSummary.setLayoutParams(layoutParams);
        }
    }

    private void setInvisible(View view) {
        if (mMode == MODE_COMPACT) {
            View articleSummary = ((View) view.getParent()).findViewById(R.id.list_item_entry_summary);
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) articleSummary.getLayoutParams();
            layoutParams.addRule(RelativeLayout.BELOW, R.id.list_item_entry_title);
            articleSummary.setLayoutParams(layoutParams);
        }
        view.setVisibility(View.GONE);
    }

    private static boolean cancelPotentialDownload(String url, ImageView imageView) {
        ImageDownloaderTask imageDownloaderTask = getImageDownloaderTask(imageView);

        if (imageDownloaderTask != null) {
            URL bitmapUrl = imageDownloaderTask.mURL;
            if ((bitmapUrl == null) || (!bitmapUrl.toString().equals(url))) {
                imageDownloaderTask.cancel(true);
            } else {
                return false;
            }
        }
        return true;
    }

    private static ImageDownloaderTask getImageDownloaderTask(ImageView imageView) {
        if (imageView != null) {
            Drawable drawable = imageView.getDrawable();
            if (drawable instanceof DownloadDrawable) {
                DownloadDrawable downloadDrawable = (DownloadDrawable) drawable;
                return downloadDrawable.getImageDownloaderTask();
            }
        }
        return null;
    }

    private static class DownloadDrawable extends ColorDrawable {
        private final WeakReference<ImageDownloaderTask> mImageDownloaderTaskReference;

        public DownloadDrawable(ImageDownloaderTask imageDownloaderTask) {
            super(Color.TRANSPARENT);
            mImageDownloaderTaskReference = new WeakReference<ImageDownloaderTask>(imageDownloaderTask);
        }

        public ImageDownloaderTask getImageDownloaderTask() {
            return mImageDownloaderTaskReference.get();
        }
    }

    /*
     * From http://stackoverflow.com/a/1856542
     */
    private static String getUniqueKey(long id, URL extUrl) {
        String filename = "";
        String path = extUrl.getPath();

        String[] pathContents = path.split("[\\\\/]");
        if (pathContents != null) {
            String lastPart = pathContents[pathContents.length - 1];
            String[] lastPartContents = lastPart.split("\\.");
            if (lastPartContents != null && lastPartContents.length > 1) {
                int lastPartContentLength = lastPartContents.length;
                String name = "";
                for (int i = 0; i < lastPartContentLength; i++) {
                    if (i < (lastPartContents.length - 1)) {
                        name += lastPartContents[i];
                        if (i < (lastPartContentLength - 2)) {
                            name += ".";
                        }
                    }
                }
                String extension = lastPartContents[lastPartContentLength - 1];

                // remove linebreaks and spaces, fixes #55
                name = name.replaceAll("\\s", "");

                filename = name + "." + extension;
            }
        }
        return id + "_" + filename;
    }
}




Java Source Code List

de.hdodenhof.holoreader.Config.java
de.hdodenhof.holoreader.activities.DisplayArticleActivity.java
de.hdodenhof.holoreader.activities.DisplayFeedActivity.java
de.hdodenhof.holoreader.activities.EditFeedsActivity.java
de.hdodenhof.holoreader.activities.HoloReaderActivity.java
de.hdodenhof.holoreader.activities.HomeActivity.java
de.hdodenhof.holoreader.fragments.ArticleFragment.java
de.hdodenhof.holoreader.fragments.ArticleListFragment.java
de.hdodenhof.holoreader.fragments.CustomListFragment.java
de.hdodenhof.holoreader.fragments.DynamicDialogFragment.java
de.hdodenhof.holoreader.fragments.EditFeedsFragment.java
de.hdodenhof.holoreader.fragments.FeedListFragment.java
de.hdodenhof.holoreader.gcm.GCMIntentService.java
de.hdodenhof.holoreader.gcm.GCMReceiver.java
de.hdodenhof.holoreader.gcm.GCMServerUtilities.java
de.hdodenhof.holoreader.gcm.VOFeed.java
de.hdodenhof.holoreader.listadapters.EditFeedAdapter.java
de.hdodenhof.holoreader.listadapters.RSSAdapter.java
de.hdodenhof.holoreader.listadapters.RSSArticleAdapter.java
de.hdodenhof.holoreader.listadapters.RSSFeedAdapter.java
de.hdodenhof.holoreader.misc.ArticleViewPager.java
de.hdodenhof.holoreader.misc.ChangelogDialog.java
de.hdodenhof.holoreader.misc.CheckableLinearLayout.java
de.hdodenhof.holoreader.misc.CustomScrollView.java
de.hdodenhof.holoreader.misc.DiskLruImageCache.java
de.hdodenhof.holoreader.misc.FragmentCallback.java
de.hdodenhof.holoreader.misc.Helpers.java
de.hdodenhof.holoreader.misc.MarkReadRunnable.java
de.hdodenhof.holoreader.misc.OnArticleChangedListener.java
de.hdodenhof.holoreader.provider.RSSContentProvider.java
de.hdodenhof.holoreader.provider.SQLiteHelper.java
de.hdodenhof.holoreader.services.RefreshFeedListener.java
de.hdodenhof.holoreader.services.RefreshFeedService.java
de.hdodenhof.holoreader.tasks.AddFeedTask.java