1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.setupwizardlib;
18
19import android.annotation.TargetApi;
20import android.content.Context;
21import android.graphics.drawable.Drawable;
22import android.os.Build.VERSION_CODES;
23import android.support.v7.widget.RecyclerView;
24import android.support.v7.widget.RecyclerView.Adapter;
25import android.support.v7.widget.RecyclerView.ViewHolder;
26import android.util.AttributeSet;
27import android.view.LayoutInflater;
28import android.view.View;
29import android.view.ViewGroup;
30
31import com.android.setupwizardlib.template.RecyclerMixin;
32import com.android.setupwizardlib.template.RecyclerViewScrollHandlingDelegate;
33import com.android.setupwizardlib.template.RequireScrollMixin;
34
35/**
36 * A GLIF themed layout with a RecyclerView. {@code android:entries} can also be used to specify an
37 * {@link com.android.setupwizardlib.items.ItemHierarchy} to be used with this layout in XML.
38 */
39public class GlifRecyclerLayout extends GlifLayout {
40
41    protected RecyclerMixin mRecyclerMixin;
42
43    public GlifRecyclerLayout(Context context) {
44        this(context, 0, 0);
45    }
46
47    public GlifRecyclerLayout(Context context, int template) {
48        this(context, template, 0);
49    }
50
51    public GlifRecyclerLayout(Context context, int template, int containerId) {
52        super(context, template, containerId);
53        init(context, null, 0);
54    }
55
56    public GlifRecyclerLayout(Context context, AttributeSet attrs) {
57        super(context, attrs);
58        init(context, attrs, 0);
59    }
60
61    @TargetApi(VERSION_CODES.HONEYCOMB)
62    public GlifRecyclerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
63        super(context, attrs, defStyleAttr);
64        init(context, attrs, defStyleAttr);
65    }
66
67    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
68        mRecyclerMixin.parseAttributes(attrs, defStyleAttr);
69        registerMixin(RecyclerMixin.class, mRecyclerMixin);
70
71        final RequireScrollMixin requireScrollMixin = getMixin(RequireScrollMixin.class);
72        requireScrollMixin.setScrollHandlingDelegate(
73                new RecyclerViewScrollHandlingDelegate(requireScrollMixin, getRecyclerView()));
74    }
75
76    @Override
77    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
78        super.onLayout(changed, left, top, right, bottom);
79        mRecyclerMixin.onLayout();
80    }
81
82    @Override
83    protected View onInflateTemplate(LayoutInflater inflater, int template) {
84        if (template == 0) {
85            template = R.layout.suw_glif_recycler_template;
86        }
87        return super.onInflateTemplate(inflater, template);
88    }
89
90    @Override
91    protected void onTemplateInflated() {
92        final View recyclerView = findViewById(R.id.suw_recycler_view);
93        if (recyclerView instanceof RecyclerView) {
94            mRecyclerMixin = new RecyclerMixin(this, (RecyclerView) recyclerView);
95        } else {
96            throw new IllegalStateException(
97                    "GlifRecyclerLayout should use a template with recycler view");
98        }
99    }
100
101    @Override
102    protected ViewGroup findContainer(int containerId) {
103        if (containerId == 0) {
104            containerId = R.id.suw_recycler_view;
105        }
106        return super.findContainer(containerId);
107    }
108
109    @Override
110    public View findManagedViewById(int id) {
111        final View header = mRecyclerMixin.getHeader();
112        if (header != null) {
113            final View view = header.findViewById(id);
114            if (view != null) {
115                return view;
116            }
117        }
118        return super.findViewById(id);
119    }
120
121    /**
122     * @see RecyclerMixin#setDividerItemDecoration(DividerItemDecoration)
123     */
124    public void setDividerItemDecoration(DividerItemDecoration decoration) {
125        mRecyclerMixin.setDividerItemDecoration(decoration);
126    }
127
128    /**
129     * @see RecyclerMixin#getRecyclerView()
130     */
131    public RecyclerView getRecyclerView() {
132        return mRecyclerMixin.getRecyclerView();
133    }
134
135    /**
136     * @see RecyclerMixin#setAdapter(Adapter)
137     */
138    public void setAdapter(Adapter<? extends ViewHolder> adapter) {
139        mRecyclerMixin.setAdapter(adapter);
140    }
141
142    /**
143     * @see RecyclerMixin#getAdapter()
144     */
145    public Adapter<? extends ViewHolder> getAdapter() {
146        return mRecyclerMixin.getAdapter();
147    }
148
149    /**
150     * @see RecyclerMixin#setDividerInset(int)
151     */
152    public void setDividerInset(int inset) {
153        mRecyclerMixin.setDividerInset(inset);
154    }
155
156    /**
157     * @see RecyclerMixin#getDividerInset()
158     */
159    public int getDividerInset() {
160        return mRecyclerMixin.getDividerInset();
161    }
162
163    /**
164     * @see RecyclerMixin#getDivider()
165     */
166    public Drawable getDivider() {
167        return mRecyclerMixin.getDivider();
168    }
169}
170