Back to project page geoar-app.
The source code is released under:
Apache License
If you think the Android project geoar-app listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/** * Copyright 2012 52North Initiative for Geospatial Open Source Software GmbH *// w w w .ja v a 2 s. c o m * 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.n52.geoar.view; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.Timer; import java.util.TimerTask; import org.n52.geoar.GeoARApplication; import org.n52.geoar.R; import android.content.Context; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; /** * Core information bar. Takes records of objects which currently try to show * information and presents them as possible * * @author Holger Hopmann, Arne de Wall * */ public class InfoView extends LinearLayout { private static final int MESSAGE_REFRESH = 1; private static class ProgressHolder { private int progress, maxProgress; } private static class StatusHolder { private long clearTime; private String status = ""; private Object id; } private interface OnChangeListener { void onChange(); } private static Handler updatehandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == MESSAGE_REFRESH) { notifyStatusChangeListeners(); } } }; private OnChangeListener statusChangeListener = new OnChangeListener() { @Override public void onChange() { statusUpdate(); } }; private OnChangeListener progressChangeListener = new OnChangeListener() { @Override public void onChange() { progressUpdate(); } }; private ProgressBar infoProgressBar; // HashMaps of all identifiers and their information to show private static Map<Object, ProgressHolder> progressHolderMap = new HashMap<Object, ProgressHolder>(); private static LinkedHashMap<Object, StatusHolder> statusHolderMap = new LinkedHashMap<Object, StatusHolder>( 0, 1, true); private static Set<OnChangeListener> statusChangeListeners = new HashSet<InfoView.OnChangeListener>(); private static Set<OnChangeListener> progressChangeListeners = new HashSet<InfoView.OnChangeListener>(); private StatusHolder currentStatus; private ProgressHolder currentProgress = new ProgressHolder(); private TextView infoStatusTextView; private Runnable updateViewsRunnable = new Runnable() { public void run() { updateRunnableQueued = false; updateViews(); } }; private boolean updateRunnableQueued; public InfoView(Context context, AttributeSet attrs) { super(context, attrs); setOrientation(VERTICAL); // inflate layout LayoutInflater.from(context).inflate(R.layout.infoviews, this, true); infoStatusTextView = (TextView) findViewById(R.id.textViewStatusInfo); infoProgressBar = (ProgressBar) findViewById(R.id.progressBar); statusChangeListeners.add(statusChangeListener); progressChangeListeners.add(progressChangeListener); Timer timer = new Timer(true); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { statusUpdate(); } }, 0, 3000); statusUpdate(); updateViews(); } private void statusUpdate() { synchronized (statusHolderMap) { if (statusHolderMap.size() != 0) { // get next status to show Iterator<StatusHolder> iterator = statusHolderMap.values() .iterator(); long now = SystemClock.uptimeMillis(); currentStatus = null; // try to get the very first one which is not outdated while (iterator.hasNext()) { StatusHolder holder = iterator.next(); if (holder.clearTime <= now) { iterator.remove(); } else { currentStatus = holder; break; } } if (currentStatus != null) { // just get the object which we already have, to // update the internal access order so that that // element gets biased against the others. statusHolderMap.get(currentStatus.id); } refresh(); } else if (currentStatus != null) { currentStatus = null; } } } private void progressUpdate() { synchronized (progressHolderMap) { currentProgress.progress = 0; currentProgress.maxProgress = 0; for (ProgressHolder holder : progressHolderMap.values()) { currentProgress.progress += holder.progress; currentProgress.maxProgress += holder.maxProgress; } if (currentProgress.progress >= currentProgress.maxProgress) { for (ProgressHolder holder : progressHolderMap.values()) { clearStatus(holder); } progressHolderMap.clear(); } refresh(); } } private static void notifyStatusChangeListeners() { for (OnChangeListener listener : statusChangeListeners) listener.onChange(); } private static void notifyProgressChangeListeners() { for (OnChangeListener listener : progressChangeListeners) listener.onChange(); } /** * Allows to update views state from any thread */ private void refresh() { if (!updateRunnableQueued) { updateRunnableQueued = true; post(updateViewsRunnable); } } /** * Set the specific status for the identification object * * @param progress * @param maxProgress * @param id */ public static void setProgress(int progress, int maxProgress, Object id) { synchronized (progressHolderMap) { ProgressHolder holder = progressHolderMap.get(id); if (holder == null) { holder = new ProgressHolder(); progressHolderMap.put(id, holder); } holder.maxProgress = maxProgress; holder.progress = progress; if (holder.progress >= holder.maxProgress) { clearStatus(holder); } } notifyProgressChangeListeners(); } /** * sets a progress title for this id * * @param title * @param id */ public static void setProgressTitle(String title, Object id) { synchronized (progressHolderMap) { ProgressHolder holder = progressHolderMap.get(id); if (holder == null) { holder = new ProgressHolder(); progressHolderMap.put(id, holder); } setStatus(title, -1, holder); } } public static void setProgressTitle(int stringId, Object id) { setProgressTitle( GeoARApplication.applicationContext.getString(stringId), id); } /** * Sets status text for id * * @param stringId * @param maxDuration * @param id */ public static void setStatus(int stringId, int maxDuration, Object id) { setStatus(GeoARApplication.applicationContext.getString(stringId), maxDuration, id); } /** * Sets status text for id * * @param status * @param maxDuration * @param id */ public static void setStatus(String status, int maxDuration, Object id) { boolean update = false; synchronized (statusHolderMap) { StatusHolder holder = statusHolderMap.get(id); if (holder == null) { holder = new StatusHolder(); holder.id = id; statusHolderMap.put(id, holder); update = true; } if (holder.status != null && !holder.status.equals(status)) { update = true; } holder.status = status; if (maxDuration != -1) { holder.clearTime = SystemClock.uptimeMillis() + maxDuration; } else { holder.clearTime = Long.MAX_VALUE; } updatehandler.sendMessageAtTime( updatehandler.obtainMessage(MESSAGE_REFRESH), holder.clearTime); } if (update) { notifyStatusChangeListeners(); } } /** * Clears status text for id * * @param id */ public static void clearStatus(Object id) { synchronized (statusHolderMap) { statusHolderMap.remove(id); } notifyStatusChangeListeners(); } /** * Updates views to reflect current status and progress */ private void updateViews() { boolean isVisible = false; synchronized (progressHolderMap) { if (currentProgress.progress < currentProgress.maxProgress) { infoProgressBar.setMax(currentProgress.maxProgress); infoProgressBar.setProgress(currentProgress.progress); infoProgressBar.setVisibility(View.VISIBLE); isVisible = true; } else { infoProgressBar.setVisibility(View.GONE); } } synchronized (statusHolderMap) { if (currentStatus != null) { infoStatusTextView.setText(currentStatus.status); infoStatusTextView.setVisibility(View.VISIBLE); isVisible = true; } else { infoStatusTextView.setVisibility(View.GONE); } } if (isVisible) { setVisibility(View.VISIBLE); } else { setVisibility(View.GONE); } } /** * Clears progress by id * * @param id */ public static void clearProgress(Object id) { setProgress(0, 0, id); } }