package com.countrypicker;
import android.annotation.SuppressLint;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ListView;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Currency;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
public class CountryPicker extends DialogFragment implements
Comparator<Country> {
/**
* View components
*/
private EditText searchEditText;
private ListView countryListView;
/**
* Adapter for the listview
*/
private CountryListAdapter adapter;
/**
* Hold all countries, sorted by country name
*/
private List<Country> allCountriesList;
/**
* Hold countries that matched user query
*/
private List<Country> selectedCountriesList;
/**
* Listener to which country user selected
*/
private CountryPickerListener listener;
/**
* Set listener
*
* @param listener
*/
public void setListener(CountryPickerListener listener) {
this.listener = listener;
}
public EditText getSearchEditText() {
return searchEditText;
}
public ListView getCountryListView() {
return countryListView;
}
/**
* Convenient function to get currency code from country code currency code
* is in English locale
*
* @param countryCode
* @return
*/
public static Currency getCurrencyCode(String countryCode) {
try {
return Currency.getInstance(new Locale("en", countryCode));
} catch (Exception e) {
}
return null;
}
/**
* Get all countries with code and name from res/raw/countries.json
*
* @return
*/
private List<Country> getAllCountries() {
if (allCountriesList == null) {
try {
allCountriesList = new ArrayList<Country>();
// Read from local file
String allCountriesString = readFileAsString(getActivity());
Log.d("countrypicker", "country: " + allCountriesString);
JSONObject jsonObject = new JSONObject(allCountriesString);
Iterator<?> keys = jsonObject.keys();
// Add the data to all countries list
while (keys.hasNext()) {
String key = (String) keys.next();
Country country = new Country();
country.setCode(key);
country.setName(jsonObject.getString(key));
allCountriesList.add(country);
}
// Sort the all countries list based on country name
Collections.sort(allCountriesList, this);
// Initialize selected countries with all countries
selectedCountriesList = new ArrayList<Country>();
selectedCountriesList.addAll(allCountriesList);
// Return
return allCountriesList;
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* R.string.countries is a json string which is Base64 encoded to avoid
* special characters in XML. It's Base64 decoded here to get original json.
*
* @param context
* @return
* @throws java.io.IOException
*/
private static String readFileAsString(Context context)
throws java.io.IOException {
String base64 = context.getResources().getString(R.string.countries);
byte[] data = Base64.decode(base64, Base64.DEFAULT);
return new String(data, "UTF-8");
}
/**
* To support show as dialog
*
* @param dialogTitle
* @return
*/
public static CountryPicker newInstance(String dialogTitle) {
CountryPicker picker = new CountryPicker();
Bundle bundle = new Bundle();
bundle.putString("dialogTitle", dialogTitle);
picker.setArguments(bundle);
return picker;
}
/**
* Create view
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate view
View view = inflater.inflate(R.layout.country_picker, null);
// Get countries from the json
getAllCountries();
// Set dialog title if show as dialog
Bundle args = getArguments();
if (args != null) {
String dialogTitle = args.getString("dialogTitle");
getDialog().setTitle(dialogTitle);
int width = getResources().getDimensionPixelSize(
R.dimen.cp_dialog_width);
int height = getResources().getDimensionPixelSize(
R.dimen.cp_dialog_height);
getDialog().getWindow().setLayout(width, height);
}
// Get view components
searchEditText = (EditText) view
.findViewById(R.id.country_picker_search);
countryListView = (ListView) view
.findViewById(R.id.country_picker_listview);
// Set adapter
adapter = new CountryListAdapter(getActivity(), selectedCountriesList);
countryListView.setAdapter(adapter);
// Inform listener
countryListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (listener != null) {
Country country = selectedCountriesList.get(position);
listener.onSelectCountry(country.getName(),
country.getCode());
}
}
});
// Search for which countries matched user query
searchEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
search(s.toString());
}
});
return view;
}
/**
* Search allCountriesList contains text and put result into
* selectedCountriesList
*
* @param text
*/
@SuppressLint("DefaultLocale")
private void search(String text) {
selectedCountriesList.clear();
for (Country country : allCountriesList) {
if (country.getName().toLowerCase(Locale.ENGLISH)
.contains(text.toLowerCase())) {
selectedCountriesList.add(country);
}
}
adapter.notifyDataSetChanged();
}
/**
* Support sorting the countries list
*/
@Override
public int compare(Country lhs, Country rhs) {
return lhs.getName().compareTo(rhs.getName());
}
}