Java tutorial
/* * Androzic - android navigation client that uses OziExplorer maps (ozf2, ozfx3). * Copyright (C) 2010-2014 Andrey Novikov <http://andreynovikov.info/> * * This file is part of Androzic application. * * Androzic 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. * * Androzic 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 Androzic. If not, see <http://www.gnu.org/licenses/>. */ package com.androzic.ui; import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.SuppressLint; import android.app.Dialog; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.DialogFragment; import android.support.v7.app.AlertDialog; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; import com.androzic.R; import com.androzic.util.FileList; public abstract class FileListDialog extends DialogFragment implements OnItemClickListener { private final static String KEY_FILE = "FILE"; private final static String KEY_PATH = "DIR"; List<File> files = null; List<Map<String, String>> fileData = new ArrayList<Map<String, String>>(); ViewGroup dialogView; ListView listView; ProgressBar progressBar; protected ExecutorService threadPool = Executors.newFixedThreadPool(2); final Handler handler = new Handler(); private int shortAnimationDuration; private int title; private OnFileListDialogListener listener; public interface OnFileListDialogListener { public void onFileLoaded(int count); } public FileListDialog() { throw new RuntimeException("Unimplemented initialization context"); } public FileListDialog(int title, OnFileListDialogListener listener) { this.title = title; this.listener = listener; } @SuppressLint("InflateParams") @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(title); dialogView = (ViewGroup) getActivity().getLayoutInflater() .inflate(R.layout.list_with_empty_view_and_progressbar, null); builder.setView(dialogView); listView = (ListView) dialogView.findViewById(android.R.id.list); progressBar = (ProgressBar) dialogView.findViewById(R.id.progressbar); listView.setOnItemClickListener(this); shortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime); return builder.create(); } @Override public void onResume() { super.onResume(); listView.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); threadPool.execute(new Runnable() { public void run() { File root = new File(getPath()); files = FileList.getFileListing(root, getFilenameFilter()); /* * Collections.sort(files, new Comparator() * { * * @Override * public int compare(Object o1, Object o2) * { * return ((File) o1).getName().compareToIgnoreCase(((File) o2).getName()); * } * }); */ Map<String, String> group; for (File file : files) { group = new HashMap<String, String>(); group.put(KEY_FILE, file.getName()); group.put(KEY_PATH, file.getParent()); fileData.add(group); } handler.post(updateResults); } }); } @Override public void onPause() { super.onPause(); files = null; fileData.clear(); } final Runnable updateResults = new Runnable() { public void run() { TextView emptyView = (TextView) dialogView.findViewById(android.R.id.empty); emptyView.setText(R.string.msg_empty_map_list); listView.setEmptyView(emptyView); listView.setAdapter(new SimpleAdapter(getActivity(), fileData, android.R.layout.simple_list_item_2, new String[] { KEY_FILE, KEY_PATH }, new int[] { android.R.id.text1, android.R.id.text2 })); crossfade(true); } }; @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final File file = files.get(position); if (!file.exists()) { Toast.makeText(getActivity(), R.string.err_nofile, Toast.LENGTH_LONG).show(); dismiss(); } crossfade(false); threadPool.execute(new Runnable() { public void run() { loadFile(file); dismiss(); }; }); } @Override public void onDestroyView() { if (getDialog() != null && getRetainInstance()) getDialog().setDismissMessage(null); super.onDestroyView(); } protected void onFileLoaded(final int count) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { listener.onFileLoaded(count); } }); } abstract protected FilenameFilter getFilenameFilter(); abstract protected String getPath(); abstract protected void loadFile(File file); @SuppressLint("NewApi") private void crossfade(boolean direct) { final View from = direct ? progressBar : listView; final View to = direct ? listView : progressBar; if (!direct) { dialogView.setMinimumWidth(dialogView.getWidth()); dialogView.setMinimumHeight(dialogView.getHeight()); } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) { from.setVisibility(View.GONE); to.setVisibility(View.VISIBLE); } else { // Set the content view to 0% opacity but visible, so that it is visible // (but fully transparent) during the animation. to.setAlpha(0f); to.setVisibility(View.VISIBLE); // Animate the content view to 100% opacity, and clear any animation // listener set on the view. to.animate().alpha(1f).setDuration(shortAnimationDuration).setListener(null); // Animate the loading view to 0% opacity. After the animation ends, // set its visibility to GONE as an optimization step (it won't // participate in layout passes, etc.) from.animate().alpha(0f).setDuration(shortAnimationDuration).setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { from.setVisibility(View.GONE); } }); } } protected final Runnable wrongFormat = new Runnable() { public void run() { Toast.makeText(getActivity(), R.string.err_wrongformat, Toast.LENGTH_LONG).show(); } }; protected final Runnable readError = new Runnable() { public void run() { Toast.makeText(getActivity(), R.string.err_read, Toast.LENGTH_LONG).show(); } }; }