com.mercandalli.android.apps.files.file.FileModelCardAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.mercandalli.android.apps.files.file.FileModelCardAdapter.java

Source

/**
 * This file is part of FileSpace for Android, an app for managing your server (files, talks...).
 * <p/>
 * Copyright (c) 2014-2015 FileSpace for Android contributors (http://mercandalli.com)
 * <p/>
 * LICENSE:
 * <p/>
 * FileSpace for Android is free software: you can redistribute it and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any
 * later version.
 * <p/>
 * FileSpace for Android is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * @author Jonathan Mercandalli
 * @license http://www.gnu.org/licenses/gpl.html
 * @copyright 2014-2015 FileSpace for Android contributors (http://mercandalli.com)
 */
package com.mercandalli.android.apps.files.file;

import android.content.Context;
import android.graphics.Color;
import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.mercandalli.android.apps.files.R;
import com.mercandalli.android.apps.files.file.filespace.FileSpaceModel;
import com.mercandalli.android.library.base.java.StringUtils;
import com.mercandalli.android.library.base.precondition.Preconditions;

import java.util.ArrayList;
import java.util.List;

/**
 * The {@link FileModel} card {@link android.support.v7.widget.RecyclerView.Adapter}.
 */
public class FileModelCardAdapter extends RecyclerView.Adapter<FileModelCardAdapter.ViewHolder> {

    /**
     * The view type of the header.
     */
    public static final int TYPE_HEADER_AUDIO = 0;

    /**
     * The view type of the header.
     */
    public static final int TYPE_HEADER_IMAGE = 1;

    /**
     * The view type of the card.
     */
    private static final int TYPE_CARD_ITEM = 2;

    /**
     * The application {@link Context}.
     */
    private final Context mContextApp;
    private final List<FileModel> mFiles;
    private final OnFileClickListener mOnFileClickListener;
    private final OnFileLongClickListener mOnFileLongClickListener;
    private FileModelListener mMoreListener;
    private OnFileSubtitleAdapter mOnFileSubtitleAdapter;

    private final String mStringDirectory;
    private final String mStringFile;
    private final String mStringFiles;

    /* Header */
    private List<FileModelCardHeaderItem> mHeaderIds;
    private OnHeaderClickListener mOnHeaderClickListener;

    private int mHeaderType = TYPE_HEADER_AUDIO;

    /**
     * Adapter without header.
     */
    public FileModelCardAdapter(final Context context, final List<FileModel> files,
            final FileModelListener moreListener, final OnFileClickListener onFileClickListener,
            final OnFileLongClickListener onFileLongClickListener) {
        mContextApp = context.getApplicationContext();
        mFiles = new ArrayList<>();
        mFiles.addAll(files);
        mMoreListener = moreListener;
        mOnFileClickListener = onFileClickListener;
        mOnFileLongClickListener = onFileLongClickListener;

        mStringDirectory = context.getString(R.string.file_model_adapter_directory);
        mStringFile = context.getString(R.string.file_model_adapter_file);
        mStringFiles = context.getString(R.string.file_model_adapter_files);
        setHasStableIds(true);
    }

    /**
     * Adapter with header.
     */
    public FileModelCardAdapter(final Context context, final List<FileModelCardHeaderItem> headerIds,
            final OnHeaderClickListener onHeaderClickListener, final List<FileModel> files,
            final FileModelListener moreListener, final OnFileClickListener onFileClickListener,
            final OnFileLongClickListener onFileLongClickListener) {
        this(context, files, moreListener, onFileClickListener, onFileLongClickListener);
        mHeaderIds = new ArrayList<>();
        mHeaderIds.addAll(headerIds);
        mOnHeaderClickListener = onHeaderClickListener;
    }

    @Override
    public FileModelCardAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_HEADER_AUDIO) {
            return new HeaderViewHolder(LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.view_file_header_audio, parent, false), mHeaderIds, mOnHeaderClickListener);
        } else if (viewType == TYPE_HEADER_IMAGE) {
            return new HeaderViewHolder(LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.view_file_header_image, parent, false), mHeaderIds, mOnHeaderClickListener);
        } else if (viewType == TYPE_CARD_ITEM) {
            return new CardViewHolder(
                    LayoutInflater.from(parent.getContext()).inflate(R.layout.card_file, parent, false),
                    hasHeader(), mOnFileClickListener, mOnFileLongClickListener);
        }
        throw new RuntimeException(
                "There is no type that matches the type " + viewType + " + make sure your using types correctly.");
    }

    @Override
    public void onBindViewHolder(final ViewHolder viewHolder, final int position) {

        if (viewHolder instanceof HeaderViewHolder) {
            final HeaderViewHolder headerViewHolder = (HeaderViewHolder) viewHolder;
            headerViewHolder.setFileModelCardHeaderItems(mHeaderIds);
            return;
        }

        final FileModel fileModel = getFileModel(position);
        if (fileModel == null || !(viewHolder instanceof CardViewHolder)) {
            return;
        }

        final CardViewHolder cardViewHolder = (CardViewHolder) viewHolder;
        cardViewHolder.mTitle.setText(getAdapterTitle(fileModel));
        cardViewHolder.subtitle.setText(getAdapterSubtitle(fileModel));

        final FileTypeModel type = fileModel.getType();
        if (fileModel.isDirectory()) {
            cardViewHolder.icon.setImageResource(R.drawable.directory);
        } else if (FileTypeModelENUM.AUDIO.type.equals(type)) {
            cardViewHolder.icon.setImageResource(R.drawable.file_audio);
        } else if (FileTypeModelENUM.PDF.type.equals(type)) {
            cardViewHolder.icon.setImageResource(R.drawable.file_pdf);
        } else if (FileTypeModelENUM.APK.type.equals(type)) {
            cardViewHolder.icon.setImageResource(R.drawable.file_apk);
        } else if (FileTypeModelENUM.ARCHIVE.type.equals(type)) {
            cardViewHolder.icon.setImageResource(R.drawable.file_archive);
        } else if (FileTypeModelENUM.FILESPACE.type.equals(type)) {
            cardViewHolder.icon.setImageResource(R.drawable.file_space);
        } else {
            cardViewHolder.icon.setImageResource(R.drawable.file_default);
        }

        if (mMoreListener == null) {
            cardViewHolder.more.setVisibility(View.GONE);
        }
        cardViewHolder.more.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mMoreListener != null) {
                    mMoreListener.executeFileModel(fileModel, v);
                }
            }
        });
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return isHeader(position) ? mHeaderType : TYPE_CARD_ITEM;
    }

    @Override
    public int getItemCount() {
        return mFiles.size() + (hasHeader() ? 1 : 0);
    }

    public void setList(final List<FileModel> list) {
        Preconditions.checkNotNull(list);
        mFiles.clear();
        mFiles.addAll(list);
        notifyDataSetChanged();
    }

    public void setOnFileSubtitleAdapter(final OnFileSubtitleAdapter onFileSubtitleAdapter) {
        mOnFileSubtitleAdapter = onFileSubtitleAdapter;
    }

    public void setHeaderType(int headerType) {
        mHeaderType = headerType;
    }

    public boolean isHeader(final int position) {
        return hasHeader() && position == 0;
    }

    public boolean hasHeader() {
        return mOnHeaderClickListener != null;
    }

    private String getAdapterTitle(FileModel fileModel) {
        String adapterTitleStart = "";

        if (fileModel.getType() == null) {
            if (fileModel.getName() != null) {
                return adapterTitleStart + fileModel.getFullName();
            } else {
                return adapterTitleStart + fileModel.getUrl();
            }
        } else if (FileTypeModelENUM.FILESPACE.type.equals(fileModel.getType()) && fileModel.getContent() != null) {
            return adapterTitleStart + fileModel.getContent().getAdapterTitle();
        } else if (fileModel.getName() != null) {
            return adapterTitleStart + fileModel.getFullName();
        } else {
            return adapterTitleStart + fileModel.getUrl();
        }
    }

    private String getAdapterSubtitle(final FileModel fileModel) {
        String result;
        if (mOnFileSubtitleAdapter != null
                && (result = mOnFileSubtitleAdapter.onFileSubtitleModify(fileModel)) != null) {
            return result;
        }
        if (fileModel.isDirectory() && fileModel.getCount() != 0) {
            return mStringDirectory + ": " + StringUtils.longToShortString(fileModel.getCount()) + " "
                    + (fileModel.getCount() > 1 ? mStringFiles : mStringFile);
        }
        if (fileModel.isDirectory()) {
            return mStringDirectory;
        }

        final FileSpaceModel content;
        if (FileTypeModelENUM.FILESPACE.type.equals(fileModel.getType())
                && (content = fileModel.getContent()) != null) {
            return fileModel.getType().getTitle(mContextApp) + " "
                    + StringUtils.capitalize(content.getType().toString());
        }

        if (fileModel.getType() != null) {
            return fileModel.getType().getTitle(mContextApp);
        }
        return "";
    }

    @Nullable
    private FileModel getFileModel(final int adapterPosition) {
        if (isHeader(adapterPosition)) {
            return null;
        }
        final int filesPosition = adapterPosition - (hasHeader() ? 1 : 0);
        if (filesPosition >= mFiles.size()) {
            return null;
        }
        return mFiles.get(filesPosition);
    }

    public interface OnFileClickListener {
        void onFileCardClick(View v, int position);
    }

    public interface OnFileLongClickListener {
        boolean onFileCardLongClick(View v, int position);
    }

    public interface OnHeaderClickListener {
        /**
         * The header is clicked.
         */
        boolean onHeaderClick(View v, List<FileModelCardHeaderItem> fileModelCardHeaderItems);
    }

    public interface OnFileSubtitleAdapter {

        @Nullable
        String onFileSubtitleModify(final FileModel fileModel);
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View itemView) {
            super(itemView);
        }
    }

    private static class HeaderViewHolder extends ViewHolder implements OnClickListener {

        @ColorInt
        private final int mPrimaryColor;
        private final OnHeaderClickListener mOnHeaderClickListener;
        private final List<FileModelCardHeaderItem> mFileModelCardHeaderItems;

        public HeaderViewHolder(final View itemView, final List<FileModelCardHeaderItem> headerIds,
                final OnHeaderClickListener onHeaderClickListener) {
            super(itemView);
            Preconditions.checkNotNull(onHeaderClickListener);
            mPrimaryColor = ContextCompat.getColor(itemView.getContext(), R.color.primary);
            mOnHeaderClickListener = onHeaderClickListener;
            mFileModelCardHeaderItems = new ArrayList<>();
            mFileModelCardHeaderItems.addAll(headerIds);
            updateView();
        }

        @Override
        public void onClick(View v) {
            final int viewId = v.getId();

            boolean isElementAlreadySelected = false;
            for (FileModelCardHeaderItem f : mFileModelCardHeaderItems) {
                if (f.getId() == viewId && f.isSelected()) {
                    isElementAlreadySelected = true;
                    break;
                }
            }
            if (isElementAlreadySelected) {
                return;
            }
            for (FileModelCardHeaderItem f : mFileModelCardHeaderItems) {
                f.setSelected(f.getId() == viewId);
            }
            mOnHeaderClickListener.onHeaderClick(v, mFileModelCardHeaderItems);
            updateView();
        }

        public void setFileModelCardHeaderItems(List<FileModelCardHeaderItem> fileModelCardHeaderItems) {
            mFileModelCardHeaderItems.clear();
            mFileModelCardHeaderItems.addAll(fileModelCardHeaderItems);
            updateView();
        }

        private void updateView() {
            for (FileModelCardHeaderItem f : mFileModelCardHeaderItems) {
                final TextView tv = (TextView) itemView.findViewById(f.getId());
                tv.setOnClickListener(this);
                if (f.isSelected()) {
                    tv.setTextColor(mPrimaryColor);
                    tv.setBackgroundResource(R.drawable.file_local_audio_rounded_bg_selected);
                } else {
                    tv.setTextColor(Color.WHITE);
                    tv.setBackgroundResource(R.drawable.file_local_audio_rounded_bg);
                }
            }
        }
    }

    private static class CardViewHolder extends ViewHolder implements OnClickListener, View.OnLongClickListener {
        public final TextView mTitle;
        public final TextView subtitle;
        public final ImageView icon;
        public final View mItem;
        public final View more;
        private final OnFileClickListener mOnFileClickListener;
        private final OnFileLongClickListener mOnFileLongClickListener;
        private final boolean mHasHeader;

        public CardViewHolder(final View itemLayoutView, final boolean hasHeader,
                final OnFileClickListener onFileClickListener,
                final OnFileLongClickListener onFileLongClickListener) {
            super(itemLayoutView);
            mHasHeader = hasHeader;
            mItem = itemLayoutView.findViewById(R.id.card_file_item);
            mTitle = (TextView) itemLayoutView.findViewById(R.id.card_file_title);
            subtitle = (TextView) itemLayoutView.findViewById(R.id.card_file_subtitle);
            icon = (ImageView) itemLayoutView.findViewById(R.id.card_file_icon);
            more = itemLayoutView.findViewById(R.id.card_file_more);
            mOnFileClickListener = onFileClickListener;
            mOnFileLongClickListener = onFileLongClickListener;
            mItem.setOnClickListener(this);
            mItem.setOnLongClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (mOnFileClickListener != null) {
                mOnFileClickListener.onFileCardClick(icon, getAdapterPosition() - (mHasHeader ? 1 : 0));
            }
        }

        @Override
        public boolean onLongClick(View v) {
            return mOnFileLongClickListener != null
                    && mOnFileLongClickListener.onFileCardLongClick(v, getAdapterPosition() - (mHasHeader ? 1 : 0));
        }
    }
}