/** * Copyright (C) 2013 - 2015 the enviroCar community * * This file is part of the enviroCar app. * * The enviroCar app 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. * * The enviroCar app 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 the enviroCar app. If not, see http://www.gnu.org/licenses/. */ package org.envirocar.app.view.carselection; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.RadioButton; import android.widget.TextView; import com.afollestad.materialdialogs.MaterialDialog; import org.envirocar.app.R; import org.envirocar.core.entity.Car; import org.envirocar.core.logging.Logger; import java.util.List; import butterknife.ButterKnife; import butterknife.InjectView; /** * @author dewall */ public class CarSelectionListAdapter extends ArrayAdapter<Car> { private static final Logger LOG = Logger.getLogger(CarSelectionListAdapter.class); /** * Simple callback interface for the action types of the car list entries. */ public interface OnCarListActionCallback { /** * Called whenever a car has been selected to be the used car. * * @param car the selected car */ void onSelectCar(Car car); /** * Called whenever a car should be deleted. * * @param car the selected car. */ void onDeleteCar(Car car); } /** * Context of the current scope. */ private final Context mContext; /** * Callback */ private final OnCarListActionCallback mCallback; private Car mSelectedCar; private RadioButton mSelectedButton; private final List<Car> mCars; /** * Constructor. * * @param context the context of the current scope. * @param selectedCar the car for which the radio button gets checked. * @param values the values to show in the list. * @param callback the callback for list actions */ public CarSelectionListAdapter(Context context, Car selectedCar, List<Car> values, OnCarListActionCallback callback) { super(context, -1, values); this.mContext = context; this.mCars = values; this.mCallback = callback; this.mSelectedCar = selectedCar; } @Override public View getView(int position, View convertView, ViewGroup parent) { // First get the car for which the view needs to be created. final Car car = mCars.get(position); // Then inflate a new view for the car and create a holder LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context .LAYOUT_INFLATER_SERVICE); CarViewHolder holder = null; if (convertView == null) { convertView = inflater.inflate(R.layout .activity_car_selection_layout_carlist_entry, parent, false); holder = new CarViewHolder(convertView); convertView.setTag(holder); } else { holder = (CarViewHolder) convertView.getTag(); } // set the views holder.mFirstLineText.setText(String.format("%s - %s", car.getManufacturer(), car .getModel())); holder.mYearText.setText(Integer.toString(car.getConstructionYear())); holder.mGasolineText.setText(car.getFuelType().toString()); holder.mEngineText.setText(String.format("%s ccm", Integer.toString(car.getEngineDisplacement()))); // If this car is the selected car, then set the radio button checked. if (mSelectedCar != null && mSelectedCar.equals(car)) { mSelectedButton = holder.mRadioButton; mSelectedButton.setChecked(true); } final CarViewHolder tmpHolder = holder; // set the onClickListener of the radio button. holder.mRadioButton.setOnClickListener(v -> { if (mSelectedCar == null) { mSelectedCar = car; mSelectedButton = tmpHolder.mRadioButton; } else if (!mSelectedCar.equals(car)) { mSelectedCar = car; if (mSelectedButton != null) mSelectedButton.setChecked(false); mSelectedButton = tmpHolder.mRadioButton; } tmpHolder.mRadioButton.setChecked(true); mCallback.onSelectCar(mSelectedCar); }); // Set the onClickListener for a single row. convertView.setOnClickListener(v -> new MaterialDialog.Builder(mContext) .items(R.array.car_list_option_items) .itemsCallback((materialDialog, view, i, charSequence) -> { switch (i) { case 0: if(car.equals(mSelectedCar)) return; // Uncheck the currently checked car. if (mSelectedButton != null) { mSelectedButton.setChecked(false); } // Set the new car as selected car type. mSelectedCar = car; mSelectedButton = tmpHolder.mRadioButton; mSelectedButton.setChecked(true); // Call the callback in order to react accordingly. mCallback.onSelectCar(car); break; case 1: // Uncheck the the previously checked radio button and update the // references accordingly. if (car.equals(mSelectedCar)) { mSelectedCar = null; mSelectedButton.setChecked(false); mSelectedButton = null; } // Call the callback mCallback.onDeleteCar(car); break; default: LOG.warn("No action selected!"); } }) .show()); // Return the created view. return convertView; } @Override public Car getItem(int position) { return mCars.get(position); } /** * Adds a new {@link Car} to the list and finally invalidates the lsit. * * @param car the car to add to the list */ protected void addCarItem(Car car) { this.mCars.add(car); notifyDataSetChanged(); } /** * Removes a {@link Car} from the list and finally invalidates the list. * * @param car the car to remove from the list. */ protected void removeCarItem(Car car) { if (mCars.contains(car)) { mCars.remove(car); notifyDataSetChanged(); } } /** * Static view holder class that holds all necessary views of a list-row. */ static class CarViewHolder { protected final View mCoreView; @InjectView(R.id.activity_car_selection_layout_carlist_entry_icon) protected ImageView mIconView; @InjectView(R.id.activity_car_selection_layout_carlist_entry_firstline) protected TextView mFirstLineText; @InjectView(R.id.activity_car_selection_layout_carlist_entry_engine) protected TextView mEngineText; @InjectView(R.id.activity_car_selection_layout_carlist_entry_gasoline) protected TextView mGasolineText; @InjectView(R.id.activity_car_selection_layout_carlist_entry_year) protected TextView mYearText; @InjectView(R.id.activity_car_selection_layout_carlist_entry_radio) protected RadioButton mRadioButton; /** * Constructor. * * @param view */ CarViewHolder(View view) { this.mCoreView = view; ButterKnife.inject(this, view); } } }