154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey/*
254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project
354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey *
454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * you may not use this file except in compliance with the License.
654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * You may obtain a copy of the License at
754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey *
854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey *
1054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
1154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
1254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * See the License for the specific language governing permissions and
1454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * limitations under the License.
1554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey */
1654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
1754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeypackage com.android.documentsui;
1854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
1954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.database.DataSetObserver;
2054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.View;
2154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.ViewGroup;
2254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.BaseAdapter;
2354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.LinearLayout;
2454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.ListAdapter;
2554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.ListView;
2654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
2754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport com.android.internal.util.Preconditions;
2854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
2954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey/**
3054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * Adapter that wraps an existing adapter, presenting its contents in multiple
3154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * equally-sized horizontal columns.
3254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey */
3354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeypublic class ColumnAdapter extends BaseAdapter {
3454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    private final ListAdapter mWrapped;
3554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    private final OnItemClickListener mListener;
3654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
3754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    private int mColumns = 1;
3854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
3954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public interface OnItemClickListener {
4054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public void onItemClick(ListAdapter adapter, int position);
4154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
4254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
4354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public ColumnAdapter(ListAdapter wrapped, OnItemClickListener listener) {
4454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        mWrapped = Preconditions.checkNotNull(wrapped);
4554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        mListener = Preconditions.checkNotNull(listener);
4654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
4754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        if (!wrapped.areAllItemsEnabled()) {
4854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            throw new IllegalStateException("All items must be enabled");
4954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
5054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        if (wrapped.getViewTypeCount() > 1) {
5154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            throw new IllegalStateException("All items must be identical");
5254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
5354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
5454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
5554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public static void prepare(ListView list) {
5654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        list.setItemsCanFocus(true);
5754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
5854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
5954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public void setColumns(int columns) {
6054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        mColumns = columns;
6154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        notifyDataSetChanged();
6254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
6354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
6454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    private View.OnClickListener mItemListener = new View.OnClickListener() {
6554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        @Override
6654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        public void onClick(View v) {
6754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            final int position = (Integer) v.getTag();
6854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            mListener.onItemClick(mWrapped, position);
6954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
7054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    };
7154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
7254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
7354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public int getCount() {
7454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        return (mWrapped.getCount() + mColumns - 1) / mColumns;
7554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
7654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
7754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
7854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public Object getItem(int position) {
7954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        return position;
8054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
8154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
8254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
8354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public long getItemId(int position) {
8454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        return position;
8554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
8654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
8754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
8854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public View getView(int position, View convertView, ViewGroup parent) {
8954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        if (convertView == null) {
9054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            convertView = new LinearLayout(parent.getContext());
9154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
9254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
9354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
9454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                0, LinearLayout.LayoutParams.WRAP_CONTENT);
9554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        params.weight = 1f / mColumns;
9654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
9754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final LinearLayout row = (LinearLayout) convertView;
9854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final int first = position * mColumns;
9954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        final int last = mWrapped.getCount() - 1;
10054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
10154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        for (int i = 0; i < mColumns; i++) {
10254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            View convertItem = null;
10354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            if (i < row.getChildCount()) {
10454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                convertItem = row.getChildAt(i);
10554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            }
10654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
10754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            final int pos = first + i;
10854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            final int validPos = Math.min(pos, last);
10954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            final View item = mWrapped.getView(validPos, convertItem, row);
11054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            item.setTag(validPos);
11154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            item.setOnClickListener(mItemListener);
11254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            item.setFocusable(true);
11354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
11454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            if (pos == validPos) {
11554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                item.setVisibility(View.VISIBLE);
11654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            } else {
11754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                item.setVisibility(View.INVISIBLE);
11854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            }
11954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
12054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            if (convertItem == null) {
12154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey                row.addView(item, params);
12254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey            }
12354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        }
12454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
12554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        return convertView;
12654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
12754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
12854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
12954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public void registerDataSetObserver(DataSetObserver observer) {
13054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        super.registerDataSetObserver(observer);
13154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        mWrapped.registerDataSetObserver(observer);
13254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
13354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey
13454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    @Override
13554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    public void unregisterDataSetObserver(DataSetObserver observer) {
13654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        super.unregisterDataSetObserver(observer);
13754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey        mWrapped.unregisterDataSetObserver(observer);
13854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey    }
13954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey}
140