開源項目9GAG源碼解析與Material改造(一)

簡介

9GAG是一個以圖片爲主的搞笑網站,網友自發投稿,網絡全球笑料,內容以英文,尤其美國文化爲主。之前官方提供了一個開源的Android項目,不過目前官方的項目不再開源了,不過我們仍能在網上找到這個項目的源碼。
官方項目源碼
Material後的項目源碼

效果

原始效果

效果

Material之後的效果

Material

注:以上兩個只是部分效果,受CSDN對上傳圖片大小的限制沒有把所有的功能都錄製下來

分析

原項目的目錄結構

目錄結構

從項目的演示效果來看好像並不複雜,但是看一下目錄結構感覺還.java還挺多的,麻雀雖小五臟俱全,該有的都有了。所以本項目很適合新手學習一個完整項目的開發過程。整個項目的源碼解析主要可以分爲以下幾個部分
- UI
- 網絡數據交換
- 數據緩存

UI

整個講解將分爲三篇文章,本文主要講解的是UI的部分。

ListView

原項目中使用的是StaggeredGridView,是個開源項目,但是目前的這個項目的作者已經把這個項目Deprecated,推薦我們使用官方的RecyclerView,但是RecyclerView目前不支持CursorAdapter,Google官方也沒有提供解決方案,所以在Material的過程中直接使用了ListView,並用CursorAdapter作爲適配器。

CursorAdapter

CursorAdapter使用起來很簡單,主要重寫newView()和bindView()這兩個方法。需要注意的一點是,cursor的必須要有個命名爲”_id”的列。比如Contacts._ID就爲”_id”

newView返回的是一個用於裝載ListView中item的View。

public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
        return mLayoutInflater.inflate(R.layout.listitem_feed, null);
    }

bindView()的目的就是把view中的元素給附上值。

public abstract void bindView (View view, Context context, Cursor cursor)
Bind an existing view to the data pointed to by cursor

Parameters
view Existing view, returned earlier by newView
context Interface to application’s global information
cursor The cursor from which to get the data. The cursor is already moved to the correct position.

  @Override
    public void bindView(View view, Context context, Cursor cursor) {

        ViewHolder holder = (ViewHolder) view.getTag();
        if (holder == null) {
            holder = new ViewHolder(view);
            view.setTag(holder);
        }
        Feed feed = Feed.fromCursor(cursor);
        view.setEnabled(!mListView.isItemChecked(cursor.getPosition()
                + mListView.getHeaderViewsCount()));
        holder.imageRequest = ImageCacheManager.loadImage(feed.getImages().normal, ImageCacheManager
                .getImageListener(holder.imageView, mDefaultImageDrawable, mDefaultImageDrawable), 0, DensityUtils.dip2px(context, IMAGE_MAX_HEIGHT));
        holder.caption.setText(feed.getCaption());
    }

     class ViewHolder{
        @Bind(R.id.iv_normal)
        ImageView imageView;
        @Bind(R.id.tv_caption)
        TextView caption;

        public ImageLoader.ImageContainer imageRequest;

        public ViewHolder(View view){
            ButterKnife.bind(this, view);
        }
    }

FoldingDrawerLayout

FoldingDrawerLayout是繼承自DrawerLayout的一個類,用來實現摺疊效果的Drawer,在Material的過程中,使用android.support.v4.widget.DrawerLayout和android.support.design.widget.NavigationView代替。

PhotoView

一個很好的開源項目,實現了對於ImageView我們常用的操作,比如放大、縮小、旋轉等效果。
一個簡單的示例

ImageView mImageView;
PhotoViewAttacher mAttacher;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Any implementation of ImageView can be used!
    mImageView = (ImageView) findViewById(R.id.iv_photo);

    // Set the Drawable displayed
    Drawable bitmap = getResources().getDrawable(R.drawable.wallpaper);
    mImageView.setImageDrawable(bitmap);

    // Attach a PhotoViewAttacher, which takes care of all of the zooming functionality.
    mAttacher = new PhotoViewAttacher(mImageView);
}


// If you later call mImageView.setImageDrawable/setImageBitmap/setImageResource/etc then you just need to call
mAttacher.update();

具體用法參考PhotoView

ProgressWhell和LoadingFooter

原項目中這兩個都是自定義的View,還藉助了Titanic實現一些效果,在Material中都使用了ProgressBar代替(追求全面Material~~)

總結

還有一些其他的UI組件,我就不一一介紹了,畢竟學習這個項目的重點並不是關於UI的學習,項目的架構,網絡數據的交換,緩存的設置纔是主要要學習的地方。下面兩篇文章將重點對這兩個部分進行講解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章