/* * Copyright (C) 2012 Paul Watts (paulcwatts@gmail.com) * * 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 org.onebusaway.android.ui; import org.onebusaway.android.R; import org.onebusaway.android.app.Application; import org.onebusaway.android.util.ArrayAdapter; import org.onebusaway.android.util.UIUtils; import android.content.Context; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Build; import android.support.v4.content.ContextCompat; import android.support.v4.graphics.drawable.DrawableCompat; import android.text.style.ClickableSpan; import android.view.View; import android.widget.ListView; import android.widget.TextView; import java.util.Collection; class AlertList { interface Alert { public static final int TYPE_ERROR = 1; public static final int TYPE_WARNING = 2; public static final int TYPE_INFO = 3; public static final int TYPE_SHOW_HIDDEN_ALERTS = 4; // Adds an affordance to show that it's clickable // and you can see more.. public static final int FLAG_HASMORE = 0x1; String getId(); int getType(); int getFlags(); CharSequence getString(); void onClick(); } // // Adapter // private static class Adapter extends ArrayAdapter<Alert> { public Adapter(Context context) { super(context, R.layout.alert_item); } /** * Initialize the views - if the alert is a service alert that should be shown, populate * that text. If its a response error (i.e., couldn't update from server), show that. * If it's an alert showing that some alerts are filtered, show that. */ @Override protected void initView(View view, final Alert alert) { TextView alertView = (TextView) view.findViewById(android.R.id.text1); View filterGroupView = view.findViewById(R.id.filter_alert_group); TextView filterTextView = (TextView) view.findViewById(R.id.filter_alert_text); TextView showAllView = (TextView) view.findViewById(R.id.show_all_alerts); alertView.setText(alert.getString()); boolean clickable = (alert.getFlags() & Alert.FLAG_HASMORE) == Alert.FLAG_HASMORE; int type = alert.getType(); Resources r = Application.get().getResources(); int bg = R.color.alert_text_background_info; int arrowColor = R.color.alert_text_color_info; int alertColor = R.color.alert_icon_info; int resourceIdAlert = 0; switch (type) { case Alert.TYPE_ERROR: bg = R.color.alert_text_background_error; arrowColor = R.color.alert_text_color_error; resourceIdAlert = R.drawable.ic_alert_warning; alertColor = R.color.alert_icon_error; alertView.setVisibility(View.VISIBLE); filterGroupView.setVisibility(View.GONE); break; case Alert.TYPE_WARNING: bg = R.color.alert_text_background_warning; arrowColor = R.color.alert_text_color_warning; resourceIdAlert = R.drawable.ic_alert_warning; alertColor = R.color.alert_icon_warning; alertView.setVisibility(View.VISIBLE); filterGroupView.setVisibility(View.GONE); break; case Alert.TYPE_SHOW_HIDDEN_ALERTS: alertView.setVisibility(View.GONE); filterGroupView.setVisibility(View.VISIBLE); filterTextView.setText(alert.getString()); break; case Alert.TYPE_INFO: default: bg = R.color.alert_text_background_info; arrowColor = R.color.alert_text_color_info; alertView.setVisibility(View.VISIBLE); filterGroupView.setVisibility(View.GONE); break; } // Set text color to same as arrow color alertView.setTextColor(r.getColor(arrowColor)); Drawable dWarning; Drawable wdWarning = null; if (resourceIdAlert != 0) { dWarning = ContextCompat .getDrawable(Application.get().getApplicationContext(), resourceIdAlert); wdWarning = DrawableCompat.wrap(dWarning); wdWarning = wdWarning.mutate(); // Tint the icon DrawableCompat.setTint(wdWarning, r.getColor(alertColor)); } Drawable dArrow; Drawable wdArrow = null; int resourceIdArrow = clickable ? R.drawable.ic_navigation_chevron_right : 0; if (resourceIdArrow != 0) { dArrow = ContextCompat .getDrawable(Application.get().getApplicationContext(), resourceIdArrow); wdArrow = DrawableCompat.wrap(dArrow); wdArrow = wdArrow.mutate(); // Tint the icon DrawableCompat.setTint(wdArrow, r.getColor(arrowColor)); } alertView.setCompoundDrawablesWithIntrinsicBounds(wdWarning, null, wdArrow, null); // Set the background color view.setBackgroundResource(bg); // Even if we don't think it's clickable, we still need to // reset the onclick listener because we could be reusing this view. View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { alert.onClick(); } }; view.setOnClickListener(listener); // Remove any previous clickable spans - we're recycling views between fragments for efficiency UIUtils.removeAllClickableSpans(showAllView); ClickableSpan showAllClick = new ClickableSpan() { public void onClick(View v) { alert.onClick(); } }; UIUtils.setClickableSpan(showAllView, showAllClick); } } private Adapter mAdapter; private boolean mIsAlertHidden; private int mHiddenAlertCount; // // Cached views // private ListView mView; AlertList(Context context) { mAdapter = new Adapter(context); } void initView(View view) { mView = (ListView) view; mView.setAdapter(mAdapter); } // // Array / adapter methods // void add(Alert alert) { mAdapter.add(alert); } void addAll(Collection<? extends Alert> alerts) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { mAdapter.addAll(alerts); } else { for (Alert a : alerts) { mAdapter.add(a); } } } void insert(Alert alert, int index) { mAdapter.insert(alert, index); } int getPosition(Alert alert) { return mAdapter.getPosition(alert); } void remove(Alert alert) { mAdapter.remove(alert); } int getCount() { return mAdapter.getCount(); } Alert getItem(int position) { return mAdapter.getItem(position); } /** * Returns true if some alerts have previously been hidden that would otherwise * appear in this list, false if all alerts are visible * * @return true if some alerts have previously been hidden that would otherwise * appear in this list, false if all alerts are visible */ public boolean isAlertHidden() { return mIsAlertHidden; } /** * Set to true if there are some alerts that have been previously hidden that would * otherwise appear in this list, , false if all alerts are visible * * @param alertHidden true if there are some alerts that have been previously hidden that would * otherwise appear in this list, false if all alerts are visible */ public void setAlertHidden(boolean alertHidden) { mIsAlertHidden = alertHidden; } /** * Returns the number of active alerts hidden that would otherwise appear in this list * * @return the number of active alerts hidden that would otherwise appear in this list */ public int getHiddenAlertCount() { return mHiddenAlertCount; } /** * Sets the number of active alerts hidden that would otherwise appear in this list * * @param hiddenAlertCount the number of active alerts hidden that would otherwise appear in * this list */ public void setHiddenAlertCount(int hiddenAlertCount) { mHiddenAlertCount = hiddenAlertCount; } }