/* * Copyright (C) 2016 Thomas Robert Altstidl * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.tr4android.support.extension.internal; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.StateListDrawable; import android.graphics.drawable.shapes.OvalShape; import android.graphics.drawable.shapes.Shape; import android.os.Build; import android.support.v4.content.ContextCompat; import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.widget.AppCompatDrawableManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.tr4android.appcompat.extension.R; import com.tr4android.support.extension.utils.ThemeUtils; import com.tr4android.support.extension.utils.ViewCompatUtils; import com.tr4android.support.extension.widget.AccountHeaderView; import com.tr4android.support.extension.widget.CircleImageView; import java.util.ArrayList; import java.util.Arrays; /** * Adapter for accounts */ public class AccountAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private static final int VIEW_TYPE_ACCOUNT = 0; private static final int VIEW_TYPE_HEADER = 1; private ArrayList<Account> mAccounts; private ArrayList<Boolean> mChecked; private AccountHeaderView mHeader; private boolean mShowAccountAdd; private boolean mShowAccountManage; private boolean mShowCheckBoxes; private final View.OnClickListener mAccountClickListener = new View.OnClickListener() { @Override public void onClick(View view) { mHeader.handleAccountClick((Integer) view.getTag()); } }; private final CompoundButton.OnCheckedChangeListener mAccountCheckListener = new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton view, boolean isChecked) { int position = (Integer) ((View) view.getParent()).getTag(); mChecked.set(position, isChecked); mHeader.handleAccountCheck(position, isChecked); } }; public AccountAdapter(ArrayList<Account> accounts, AccountHeaderView header, boolean showAccountAdd, boolean showAccountManage, boolean showCheckBoxes) { mAccounts = accounts; mChecked = new ArrayList<>(); mHeader = header; mShowAccountAdd = showAccountAdd; mShowAccountManage = showAccountManage; mShowCheckBoxes = showCheckBoxes; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case VIEW_TYPE_ACCOUNT: AccountViewHolder holder = new AccountViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.appcompat_extension_account_list_item, parent, false)); holder.itemView.setOnClickListener(mAccountClickListener); return holder; case VIEW_TYPE_HEADER: return new HeaderViewHolder(mHeader); } return null; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof AccountViewHolder) { final AccountViewHolder accountViewHolder = (AccountViewHolder) holder; holder.itemView.setTag(position); if (position < getAccountCount()) { if (mShowCheckBoxes) { accountViewHolder.checkView.setOnCheckedChangeListener(null); accountViewHolder.checkView.setChecked(mChecked.get(position)); accountViewHolder.checkView.setOnCheckedChangeListener(mAccountCheckListener); accountViewHolder.checkView.setVisibility(View.VISIBLE); accountViewHolder.iconView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { accountViewHolder.checkView.toggle(); } }); } Account account = mAccounts.get(position); // apply the account to the list item account.applyAccountIcon(accountViewHolder.iconView); account.applyAccountEmail(accountViewHolder.nameView); account.applyAccountInfo(accountViewHolder.infoLayout, accountViewHolder.infoIconView, accountViewHolder.infoTextView); } else if (position == getItemCount() - 1 && mShowAccountManage) { // Manage accounts item accountViewHolder.iconView.setCircleImageEnabled(false); accountViewHolder.checkView.setVisibility(View.GONE); accountViewHolder.iconView.setImageResource(R.drawable.ic_settings_black_24dp); accountViewHolder.nameView.setText(R.string.account_header_list_item_manage_accounts); accountViewHolder.infoLayout.setVisibility(View.GONE); } else { // Add account item accountViewHolder.iconView.setCircleImageEnabled(false); accountViewHolder.checkView.setVisibility(View.GONE); accountViewHolder.iconView.setImageResource(R.drawable.ic_add_black_24dp); accountViewHolder.nameView.setText(R.string.account_header_list_item_add_account); accountViewHolder.infoLayout.setVisibility(View.GONE); } } } @Override public int getItemCount() { return mAccounts.size() + (mShowAccountAdd ? 1 : 0) + (mShowAccountManage ? 1 : 0); } @Override public int getItemViewType(int position) { return (position == 0) ? VIEW_TYPE_HEADER : VIEW_TYPE_ACCOUNT; } private static class AccountViewHolder extends RecyclerView.ViewHolder { CircleImageView iconView; CheckBox checkView; TextView nameView; LinearLayout infoLayout; ImageView infoIconView; TextView infoTextView; public AccountViewHolder(View itemView) { super(itemView); iconView = (CircleImageView) itemView.findViewById(R.id.icon); checkView = (CheckBox) itemView.findViewById(R.id.checkbox); nameView = (TextView) itemView.findViewById(R.id.name); infoLayout = (LinearLayout) itemView.findViewById(R.id.info_layout); infoIconView = (ImageView) itemView.findViewById(R.id.info_icon); infoTextView = (TextView) itemView.findViewById(R.id.info_text); setupCheckBox(checkView); } } private static class HeaderViewHolder extends RecyclerView.ViewHolder { public HeaderViewHolder(View itemView) { super(itemView); } } // Function for styling the CheckBox for all Android version private static void setupCheckBox(CheckBox checkBox) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { checkBox.setButtonDrawable(R.drawable.btn_checkbox_circle); checkBox.setBackgroundResource(R.drawable.btn_checkbox_circle_background); } else { Context context = checkBox.getContext(); AppCompatDrawableManager dm = AppCompatDrawableManager.get(); StateListDrawable button = new StateListDrawable(); button.addState(new int[]{android.R.attr.state_checked}, dm.getDrawable(context, R.drawable.ic_checkbox_circle_checked)); button.addState(new int[]{}, dm.getDrawable(context, R.drawable.ic_checkbox_circle_unchecked)); ColorStateList buttonTint = new ColorStateList(new int[][]{ // states new int[]{android.R.attr.state_checked}, new int[]{} // state_default }, new int[]{ // colors ThemeUtils.getThemeAttrColor(context, R.attr.colorControlActivated), ThemeUtils.getThemeAttrColor(context, R.attr.colorControlNormal) }); Drawable buttonCompat = DrawableCompat.wrap(button); DrawableCompat.setTintList(buttonCompat, buttonTint); checkBox.setButtonDrawable(buttonCompat); ShapeDrawable background = new ShapeDrawable(new OvalShape()); int backgroundTint = ThemeUtils.getThemeAttrColor(context, android.R.attr.colorBackground); Drawable backgroundCompat = DrawableCompat.wrap(background); DrawableCompat.setTint(backgroundCompat, backgroundTint); ViewCompatUtils.setBackground(checkBox, backgroundCompat); } } public int getAccountCount() { return mAccounts.size(); } public boolean isAccountAddEnabled() { return mShowAccountAdd; } public boolean isAccountManageEnabled() { return mShowAccountManage; } // Functions for managing the accounts public void add(Account account) { mAccounts.add(account); mChecked.add(false); } public void addAll(Account... accounts) { mAccounts.addAll(Arrays.asList(accounts)); Boolean[] checked = new Boolean[accounts.length]; Arrays.fill(checked, false); mChecked.addAll(Arrays.asList(checked)); } public void remove(Account account) { int index = indexOf(account); mAccounts.remove(index); mChecked.remove(index); } public void insert(Account account, int position) { mAccounts.add(position, account); mChecked.add(position, false); } public void clear() { mAccounts.clear(); mChecked.clear(); } public void move(Account account, int position) { int index = indexOf(account); mAccounts.remove(index); boolean checked = mChecked.remove(index); mAccounts.add(position, account); mChecked.add(position, checked); } public int indexOf(Account account) { return mAccounts.indexOf(account); } public Account get(int position) { return mAccounts.get(position); } public ArrayList<Account> getAll() { return mAccounts; } public void setChecked(int position, boolean checked) { mChecked.set(position, checked); } public boolean isChecked(int position) { return position == 0 || mChecked.get(position); } public ArrayList<Account> getChecked() { int size = mAccounts.size(); ArrayList<Account> checked = new ArrayList<>(size); for (int i = 0; i < size; i++) { if (isChecked(i)) checked.add(mAccounts.get(i)); } return checked; } }