Saturday, January 23, 2016

Understanding Architecture of Nick Butcher's Plaid App - Part-4

FeedAdapter - FeedAdapter.java


Adapter for the main screen grid of items
  • holds on to an activity ref for the shared element transitions
  • It’s really just like any other recyclerview adapter with layout inflation in onCreateView () and binding of views to viewholders in onBindView()  
  • it deals with following items  : - private List<PlaidItem> items;
  • It deals with four different itemview types  
    •  private static final int TYPE_DESIGNER_NEWS_STORY = 0;
    •  private static final int TYPE_DRIBBBLE_SHOT = 1;
    •  private static final int TYPE_PRODUCT_HUNT_POST = 2;
    •  private static final int TYPE_LOADING_MORE = -1;  
This adapter initialized is initialized in HomeActivity.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 @Bind(R.id.stories_grid) RecyclerView grid;

     private FeedAdapter adapter;


adapter = new FeedAdapter(this, dataManager, columns, PocketUtils.isPocketInstalled(this));

        grid.setAdapter(adapter);

        layoutManager = new GridLayoutManager(this, columns);

        layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {

            @Override

            public int getSpanSize(int position) {

                return adapter.getItemColumnSpan(position);

            }

        });


        grid.setLayoutManager(layoutManager);

        grid.addOnScrollListener(gridScroll);

        grid.addOnScrollListener(new InfiniteScrollListener(layoutManager, dataManager) {

            @Override

            public void onLoadMore() {

                dataManager.loadAllDataSources();

            }

        });

        grid.setHasFixedSize(true);

        grid.addItemDecoration(new GridItemDividerDecoration(adapter.getDividedViewHolderClasses(),

                this, R.dimen.divider_height, R.color.divider));

        grid.setItemAnimator(new HomeGridItemAnimator());


Its important to note that the  TYPE_LOADING_MORE is returned when the scrolled position is more than the items in  the List<PlaidItems>

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
  @Override
    public int getItemViewType(int position) {
        if (position < getDataItemCount()
                && getDataItemCount() > 0) {
            PlaidItem item = getItem(position);
            if (item instanceof Story) {
                return TYPE_DESIGNER_NEWS_STORY;
            } else if (item instanceof Shot) {
                return TYPE_DRIBBBLE_SHOT;
            } else if (item instanceof Post) {
                return TYPE_PRODUCT_HUNT_POST;
            }
        }
        return TYPE_LOADING_MORE;
    }
 
Lets look at  onCreateViewHolder ()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
  @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_DESIGNER_NEWS_STORY:
                return createDesignerNewsStoryHolder(parent);
            case TYPE_DRIBBBLE_SHOT:
                return createDribbbleShotHolder(parent);
            case TYPE_PRODUCT_HUNT_POST:
                return createProductHuntStoryHolder(parent);
            case TYPE_LOADING_MORE:
                return new LoadingMoreHolder(
                        layoutInflater.inflate(R.layout.infinite_loading, parent, false));
        }
        return null;
    }
So every routine create******Holder(parent) is responsible for the click events and touch events for the items present in the layout.
Click causes new activity to be launched while the touch causes the gif drawable  motion, giving an example of createDribbbleShotHolder () 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 @NonNull
    private DribbbleShotHolder createDribbbleShotHolder(ViewGroup parent) {
        final DribbbleShotHolder holder = new DribbbleShotHolder(
                layoutInflater.inflate(R.layout.dribbble_shot_item, parent, false));
        holder.image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                holder.itemView.setTransitionName(holder.itemView.getResources().getString(R
                        .string.transition_shot));
                holder.itemView.setBackgroundColor(
                        ContextCompat.getColor(host, R.color.background_light));
                Intent intent = new Intent();
                intent.setClass(host, DribbbleShot.class);
                intent.putExtra(DribbbleShot.EXTRA_SHOT,
                        (Shot) getItem(holder.getAdapterPosition()));
                setGridItemContentTransitions(holder.itemView);
                ActivityOptions options =
                        ActivityOptions.makeSceneTransitionAnimation(host,
                                Pair.create(view, host.getString(R.string.transition_shot)),
                                Pair.create(view, host.getString(R.string
                                        .transition_shot_background)));
                host.startActivity(intent, options.toBundle());
            }
        });
        // play animated GIFs whilst touched
        holder.image.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // check if it's an event we care about, else bail fast
                final int action = event.getAction();
                if (!(action == MotionEvent.ACTION_DOWN
                        || action == MotionEvent.ACTION_UP
                        || action == MotionEvent.ACTION_CANCEL)) return false;

                // get the image and check if it's an animated GIF
                final Drawable drawable = holder.image.getDrawable();
                if (drawable == null) return false;
                GifDrawable gif = null;
                if (drawable instanceof GifDrawable) {
                    gif = (GifDrawable) drawable;
                } else if (drawable instanceof TransitionDrawable) {
                    // we fade in images on load which uses a TransitionDrawable; check its layers
                    TransitionDrawable fadingIn = (TransitionDrawable) drawable;
                    for (int i = 0; i < fadingIn.getNumberOfLayers(); i++) {
                        if (fadingIn.getDrawable(i) instanceof GifDrawable) {
                            gif = (GifDrawable) fadingIn.getDrawable(i);
                            break;
                        }
                    }
                }
                if (gif == null) return false;
                // GIF found, start/stop it on press/lift
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        gif.start();
                        break;
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        gif.stop();
                        break;
                }
                return false;
            }
        });
        return holder;
    }

No comments:

Post a Comment