/*
* Copyright (C) 2015-2016 Willi Ye <williye97@gmail.com>
*
* This file is part of Kernel Adiutor.
*
* Kernel Adiutor 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 3 of the License, or
* (at your option) any later version.
*
* Kernel Adiutor 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.
*
* You should have received a copy of the GNU General Public License
* along with Kernel Adiutor. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.grarak.kerneladiutor.views.recyclerview;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.PopupMenu;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.grarak.kerneladiutor.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by willi on 18.04.16.
*/
public class CardView extends RecyclerViewItem {
public interface OnMenuListener {
void onMenuReady(CardView cardView, PopupMenu popupMenu);
}
private Activity mActivity;
private android.support.v7.widget.CardView mRootView;
private View mTitleParent;
private TextView mTitle;
private AppCompatImageView mArrow;
private View mLayoutParent;
private LinearLayout mLayout;
private View mMenuButton;
private CharSequence mTitleText;
private PopupMenu mPopupMenu;
private OnMenuListener mOnMenuListener;
private List<RecyclerViewItem> mItems = new ArrayList<>();
private HashMap<RecyclerViewItem, View> mViews = new HashMap<>();
private List<RecyclerViewItem> mLoading = new ArrayList<>();
private List<Runnable> mRunnables = new ArrayList<>();
private int mLayoutHeight;
private ValueAnimator mLayoutAnimator;
private boolean mShowLayout = true;
public CardView(Activity activity) {
if (activity == null) {
throw new IllegalStateException("Activity can't be null");
}
mActivity = activity;
}
@Override
public int getLayoutRes() {
return R.layout.rv_card_view;
}
@Override
public void onRecyclerViewCreate(Activity activity) {
super.onRecyclerViewCreate(activity);
for (RecyclerViewItem item : mItems) {
item.onRecyclerViewCreate(activity);
}
}
private void initLayouts(View view) {
mRootView = (android.support.v7.widget.CardView) view;
mTitleParent = view.findViewById(R.id.title_parent);
mTitle = (TextView) view.findViewById(R.id.card_title);
mArrow = (AppCompatImageView) view.findViewById(R.id.arrow_image);
mLayoutParent = view.findViewById(R.id.layout_parent);
mLayout = (LinearLayout) view.findViewById(R.id.card_layout);
}
@Override
void onCreateHolder(ViewGroup parent, View view) {
super.onCreateHolder(parent, view);
initLayouts(view);
setupLayout();
}
@Override
public void onCreateView(View view) {
initLayouts(view);
mMenuButton = view.findViewById(R.id.menu_button);
mMenuButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mPopupMenu != null) {
mPopupMenu.show();
}
}
});
mLayoutParent.setVisibility(mShowLayout ? View.VISIBLE : View.GONE);
mArrow.setRotationX(mShowLayout ? 0 : 180);
mTitleParent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mLayoutParent.getVisibility() == View.VISIBLE) {
mLayoutHeight = mLayoutParent.getHeight();
}
if (mLayoutAnimator == null) {
mShowLayout = !mShowLayout;
animateLayout(!mShowLayout);
viewChanged();
}
}
});
super.onCreateView(view);
}
private void animateLayout(final boolean collapse) {
mArrow.animate().rotationX(collapse ? 180 : 0).setDuration(500).start();
mLayoutAnimator = ValueAnimator.ofInt(collapse ? mLayoutHeight : 0, collapse ? 0 : mLayoutHeight);
mLayoutAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setLayoutParentHeight((int) animation.getAnimatedValue());
}
});
mLayoutAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mLayoutParent.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mLayoutParent.setVisibility(collapse ? View.GONE : View.VISIBLE);
setLayoutParentHeight(collapse ? 0 : ViewGroup.LayoutParams.MATCH_PARENT);
mLayoutAnimator = null;
}
});
mLayoutAnimator.setDuration(500);
mLayoutAnimator.start();
}
private void setLayoutParentHeight(int height) {
ViewGroup.LayoutParams layoutParams = mLayout.getLayoutParams();
layoutParams.height = height;
mLayout.requestLayout();
viewChanged();
}
public void setTitle(CharSequence title) {
mTitleText = title;
refresh();
}
public void addItem(final RecyclerViewItem item) {
if (item == this) {
throw new IllegalStateException("Cardinception!");
}
mItems.add(item);
addView(item);
}
public void setOnMenuListener(OnMenuListener onMenuListener) {
mOnMenuListener = onMenuListener;
refresh();
}
public int size() {
return mItems.size();
}
public void removeItem(RecyclerViewItem item) {
mItems.remove(item);
if (mLayout != null) {
mLayout.removeView(mViews.get(item));
}
}
public void clearItems() {
mRunnables.clear();
mItems.clear();
if (mLayout != null) {
mLayout.removeAllViews();
}
}
private void setupLayout() {
if (mLayout != null) {
mLayout.removeAllViews();
for (final RecyclerViewItem item : mItems) {
addView(item);
}
}
}
private void addView(final RecyclerViewItem item) {
Runnable runnable = new Runnable() {
@Override
public void run() {
if (mLoading.contains(item)) {
return;
}
mLoading.add(item);
View view = LayoutInflater.from(mActivity).inflate(item.getLayoutRes(), null, false);
mViews.put(item, view);
item.setOnViewChangeListener(getOnViewChangedListener());
item.onCreateView(view);
if (mLayout != null) {
mLayout.addView(view);
}
quit();
}
private void quit() {
mLoading.remove(item);
mRunnables.remove(this);
if (mRunnables.size() > 0 && mRunnables.get(0) != null) {
mActivity.runOnUiThread(mRunnables.get(0));
}
}
};
mRunnables.add(runnable);
if (mRunnables.size() == 1) {
mActivity.runOnUiThread(mRunnables.get(0));
}
}
@Override
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
super.setOnItemClickListener(onItemClickListener);
refresh();
}
@Override
public void onDestroy() {
super.onDestroy();
for (RecyclerViewItem item : mItems) {
item.onDestroy();
}
}
@Override
protected void refresh() {
super.refresh();
if (mTitle != null) {
if (mTitleText != null) {
mTitle.setText(mTitleText);
mTitleParent.setVisibility(View.VISIBLE);
if (mLayoutParent != null) {
LinearLayout.LayoutParams layoutParams =
(LinearLayout.LayoutParams) mLayout.getLayoutParams();
layoutParams.topMargin = -mLayout.getPaddingLeft();
mLayout.requestLayout();
mLayout.setPadding(mLayout.getPaddingLeft(), 0,
mLayout.getPaddingRight(), mLayout.getPaddingBottom());
}
} else {
mTitleParent.setVisibility(View.GONE);
}
}
if (mMenuButton != null && mOnMenuListener != null) {
mMenuButton.setVisibility(View.VISIBLE);
mPopupMenu = new PopupMenu(mMenuButton.getContext(), mMenuButton);
mOnMenuListener.onMenuReady(this, mPopupMenu);
}
if (mRootView != null && getOnItemClickListener() != null) {
mRootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getOnItemClickListener().onClick(CardView.this);
}
});
}
}
@Override
protected boolean cardCompatible() {
return false;
}
}