Android 开源项目分析计划(一)——Google IO 2016 共享元素过渡动画demo

本文原创,转载请注明地址:https://www.jianshu.com/p/0fd084dd836a


今天要分析的开源项目是: https://github.com/googlesamples/android-unsplash 。这是2016年Google IO大会上的一个演示demo。虽然是两年前的项目了,但还是能发现一点有用的东西。

效果如下:


2.gif
  1. 我是如何录制这个gif的?
adb shell screenrecord  /sdcard/test/1.mp4
adb pull /sdcard/test/1.mp4 .

//去ffmpeg官网下载ffmpeg:
ffmpeg.exe -i 1.mp4  -r 15  -vf fps=15,scale=270:-1  1.gif
(-r: 指定帧率
scale=width:height iw/ih 表示输入宽度/高度, -1 表示按输入尺寸等比自动计算)
  1. 项目所使用的依赖库:
dependencies {
    compile "com.android.support:support-annotations:${supportLibVersion}"
    compile "com.android.support:recyclerview-v7:${supportLibVersion}"
    compile 'com.squareup.retrofit:retrofit:1.9.0'
    compile 'com.github.bumptech.glide:glide:3.7.0'
}

minSdkVersion=21, targetSdkVersion=23

  1. 如何用RecyclerView实现gif中类似瀑布流的效果?
        RecyclerView grid;
        grid = (RecyclerView) findViewById(R.id.image_grid);
        ...
        GridLayoutManager gridLayoutManager = (GridLayoutManager) grid.getLayoutManager();
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                /* emulating https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0B6Okdz75tqQsck9lUkgxNVZza1U/style_imagery_integration_scale1.png */
                switch (position % 6) {
                    case 5:
                        return 3;
                    case 3:
                        return 2;
                    default:
                        return 1;
                }
            }
        });
        

其实就是根据position修改getSpanSize的返回值,如果spanSize为1,则表示那一张图片独占一行空间。

4.使用了Retrofit来请求 https://unsplash.it/ 的最新图片:

/**
 * Modeling the unsplash.it API.
 */
public interface UnsplashService {

    String ENDPOINT = "https://unsplash.it";

    @GET("/list")
    void getFeed(Callback> callback);

}

使用的时候:

UnsplashService unsplashApi = new RestAdapter.Builder()
                    .setEndpoint(UnsplashService.ENDPOINT)
                    .build()
                    .create(UnsplashService.class);
            unsplashApi.getFeed(new Callback>() {
                @Override
                public void success(List photos, Response response) {
                    // the first items not interesting to us, get the last 
                    relevantPhotos = new ArrayList<>(photos.subList(photos.size() - PHOTO_COUNT,
                            photos.size()));
                    populateGrid();
                }

                @Override
                public void failure(RetrofitError error) {
                    Log.e(TAG, "Error retrieving Unsplash feed:", error);
                }
            });
  1. 给RecyclerView添加白边:
        grid.addItemDecoration(new GridMarginDecoration(
                getResources().getDimensionPixelSize(R.dimen.grid_item_spacing)));//grid_item_spacing的值是2dp
public class GridMarginDecoration extends RecyclerView.ItemDecoration {

    private int space;

    public GridMarginDecoration(int space) {
        this.space = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view,
                               RecyclerView parent, RecyclerView.State state) {
        outRect.left = space;
        outRect.top = space;
        outRect.right = space;
        outRect.bottom = space;
    }
}
  1. RecyclerView的点击事件?
grid.addOnItemTouchListener(new OnItemSelectedListener(MainActivity.this) {
            public void onItemSelected(RecyclerView.ViewHolder holder, int position) {
                 ....
            }
        });

我一直以为RecyclerView没有类似ListView的OnItemClickListener,原来已经有了啊。

  1. 使用了 Data Binding.
    需要在build.gradle里手动开启:
    dataBinding {
        enabled = true
    }

具体使用细节不再描述。

  1. 如何实现共享元素的过渡动画效果?
    涉及的style有:


    

/res/transition/grid_exit.xml:


/res/transition/grid_reenter.xml:




/res/transition/shared_main_detail.xml:


    
        
            
        
        
            
        
        
        
        
    
    
        
            
        
        
        
    
    
        
            
            
        
    


涉及的方法有:

postponeEnterTransition();
getWindow().getSharedElementExitTransition().addListener(...);
postponeEnterTransition();

startPostponedEnterTransition();

setExitSharedElementCallback(...);

getWindow().setEnterTransition(...);
setEnterSharedElementCallback(...);

@Override
public void finishAfterTransition() {
    ...
}
@Override
public void onActivityReenter(int resultCode, Intent data) {
    ...
}

具体使用细节不再描述。

Over。

本文原创,转载请注明地址:https://www.jianshu.com/p/0fd084dd836a

你可能感兴趣的:(Android 开源项目分析计划(一)——Google IO 2016 共享元素过渡动画demo)