From ec56d7de88b0ceb48c7548b1d663ec73e4fe3e44 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 19 Oct 2018 02:30:33 +0200 Subject: [PATCH] added a choose country activity --- .../conversations/ui/ActionBarActivity.java | 12 ++ src/main/res/values/strings.xml | 1 + src/main/res/values/styles.xml | 8 ++ src/quick/AndroidManifest.xml | 5 + .../ui/ChooseCountryActivity.java | 129 ++++++++++++++++++ .../ui/EnterPhoneNumberActivity.java | 45 +++++- .../ui/adapter/CountryAdapter.java | 70 ++++++++++ .../utils/PhoneNumberUtilWrapper.java | 40 ++++++ .../res/layout/activity_choose_country.xml | 24 ++++ src/quick/res/layout/country_item.xml | 25 ++++ src/quick/res/menu/choose_country.xml | 11 ++ 11 files changed, 365 insertions(+), 5 deletions(-) create mode 100644 src/quick/java/eu/siacs/conversations/ui/ChooseCountryActivity.java create mode 100644 src/quick/java/eu/siacs/conversations/ui/adapter/CountryAdapter.java create mode 100644 src/quick/res/layout/activity_choose_country.xml create mode 100644 src/quick/res/layout/country_item.xml create mode 100644 src/quick/res/menu/choose_country.xml diff --git a/src/main/java/eu/siacs/conversations/ui/ActionBarActivity.java b/src/main/java/eu/siacs/conversations/ui/ActionBarActivity.java index 5741d4502..198599fd1 100644 --- a/src/main/java/eu/siacs/conversations/ui/ActionBarActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ActionBarActivity.java @@ -2,6 +2,8 @@ package eu.siacs.conversations.ui; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; +import android.view.MenuItem; + public abstract class ActionBarActivity extends AppCompatActivity { public static void configureActionBar(ActionBar actionBar) { @@ -14,4 +16,14 @@ public abstract class ActionBarActivity extends AppCompatActivity { actionBar.setDisplayHomeAsUpEnabled(upNavigation); } } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + break; + } + return super.onOptionsItemSelected(item); + } } \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 6e13f5af0..e3c1a567f 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -758,4 +758,5 @@
%s

Is this OK, or would you like to edit the number?]]>
%s is not a valid phone number. Please enter your phone number. + Search countries diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml index 0ccfd783f..e0765c0c2 100644 --- a/src/main/res/values/styles.xml +++ b/src/main/res/values/styles.xml @@ -14,6 +14,14 @@ ?TextSizeSubhead + + + + diff --git a/src/quick/AndroidManifest.xml b/src/quick/AndroidManifest.xml index 4316f2f99..7c12eee04 100644 --- a/src/quick/AndroidManifest.xml +++ b/src/quick/AndroidManifest.xml @@ -9,5 +9,10 @@ android:label="@string/verify_your_phone_number" android:launchMode="singleTask" /> + + diff --git a/src/quick/java/eu/siacs/conversations/ui/ChooseCountryActivity.java b/src/quick/java/eu/siacs/conversations/ui/ChooseCountryActivity.java new file mode 100644 index 000000000..c17776554 --- /dev/null +++ b/src/quick/java/eu/siacs/conversations/ui/ChooseCountryActivity.java @@ -0,0 +1,129 @@ +package eu.siacs.conversations.ui; + +import android.content.Context; +import android.content.Intent; +import android.databinding.DataBindingUtil; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.Toolbar; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.databinding.ActivityChooseCountryBinding; +import eu.siacs.conversations.ui.adapter.CountryAdapter; +import eu.siacs.conversations.utils.PhoneNumberUtilWrapper; + +public class ChooseCountryActivity extends ActionBarActivity implements CountryAdapter.OnCountryClicked { + + private ActivityChooseCountryBinding binding; + + private List countries = new ArrayList<>(); + private CountryAdapter countryAdapter = new CountryAdapter(countries); + private final TextWatcher mSearchTextWatcher = new TextWatcher() { + + @Override + public void afterTextChanged(final Editable editable) { + filterCountries(editable.toString()); + } + + @Override + public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) { + } + + @Override + public void onTextChanged(final CharSequence s, final int start, final int before, final int count) { + } + }; + private EditText mSearchEditText; + private final MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() { + + @Override + public boolean onMenuItemActionExpand(final MenuItem item) { + mSearchEditText.post(() -> { + mSearchEditText.requestFocus(); + final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(mSearchEditText, InputMethodManager.SHOW_IMPLICIT); + }); + + return true; + } + + @Override + public boolean onMenuItemActionCollapse(final MenuItem item) { + final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY); + mSearchEditText.setText(""); + filterCountries(null); + return true; + } + }; + private TextView.OnEditorActionListener mSearchDone = (v, actionId, event) -> { + if (countries.size() == 1) { + onCountryClicked(countries.get(0)); + } + return true; + }; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.binding = DataBindingUtil.setContentView(this, R.layout.activity_choose_country); + setSupportActionBar((Toolbar) this.binding.toolbar); + configureActionBar(getSupportActionBar()); + this.countries.addAll(PhoneNumberUtilWrapper.getCountries(this)); + Collections.sort(this.countries); + this.binding.countries.setAdapter(countryAdapter); + this.binding.countries.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); + countryAdapter.setOnCountryClicked(this); + countryAdapter.notifyDataSetChanged(); + } + + @Override + public void onCountryClicked(PhoneNumberUtilWrapper.Country country) { + Intent data = new Intent(); + data.putExtra("region", country.getRegion()); + setResult(RESULT_OK, data); + finish(); + } + + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + getMenuInflater().inflate(R.menu.choose_country, menu); + final MenuItem menuSearchView = menu.findItem(R.id.action_search); + final View mSearchView = menuSearchView.getActionView(); + mSearchEditText = mSearchView.findViewById(R.id.search_field); + mSearchEditText.addTextChangedListener(mSearchTextWatcher); + mSearchEditText.setHint(R.string.search_countries); + mSearchEditText.setOnEditorActionListener(mSearchDone); + menuSearchView.setOnActionExpandListener(mOnActionExpandListener); + return true; + } + + private void filterCountries(String needle) { + List countries = PhoneNumberUtilWrapper.getCountries(this); + Iterator iterator = countries.iterator(); + while(iterator.hasNext()) { + final PhoneNumberUtilWrapper.Country country = iterator.next(); + if(needle != null && !country.getName().toLowerCase(Locale.getDefault()).contains(needle.toLowerCase(Locale.getDefault()))) { + iterator.remove(); + } + } + this.countries.clear(); + this.countries.addAll(countries); + this.countryAdapter.notifyDataSetChanged(); + } + +} diff --git a/src/quick/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java b/src/quick/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java index d247139ac..3c25920ba 100644 --- a/src/quick/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java +++ b/src/quick/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.ui; import android.app.AlertDialog; +import android.content.Intent; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; @@ -10,7 +11,9 @@ import android.text.Html; import android.text.TextUtils; import android.text.TextWatcher; import android.util.Log; +import android.view.KeyEvent; import android.view.View; +import android.widget.TextView; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; @@ -23,6 +26,8 @@ import io.michaelrocks.libphonenumber.android.Phonenumber; public class EnterPhoneNumberActivity extends AppCompatActivity { + private static final int REQUEST_CHOOSE_COUNTRY = 0x1234; + private ActivityEnterNumberBinding binding; private String region = null; private final TextWatcher countryCodeTextWatcher = new TextWatcher() { @@ -40,8 +45,11 @@ public class EnterPhoneNumberActivity extends AppCompatActivity { public void afterTextChanged(Editable editable) { final String text = editable.toString(); try { + final int oldCode = region != null ? PhoneNumberUtilWrapper.getInstance(EnterPhoneNumberActivity.this).getCountryCodeForRegion(region) : 0; final int code = Integer.parseInt(text); - region = PhoneNumberUtilWrapper.getInstance(EnterPhoneNumberActivity.this).getRegionCodeForCountryCode(code); + if (oldCode != code) { + region = PhoneNumberUtilWrapper.getInstance(EnterPhoneNumberActivity.this).getRegionCodeForCountryCode(code); + } if ("ZZ".equals(region)) { binding.country.setText(TextUtils.isEmpty(text) ? R.string.choose_a_country : R.string.invalid_country_code); } else { @@ -57,18 +65,31 @@ public class EnterPhoneNumberActivity extends AppCompatActivity { @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + String region = savedInstanceState != null ? savedInstanceState.getString("region") : null; + if (region != null) { + this.region = region; + } else { + this.region = PhoneNumberUtilWrapper.getUserCountry(this); + } + this.binding = DataBindingUtil.setContentView(this, R.layout.activity_enter_number); this.binding.countryCode.setCompoundDrawables(new TextDrawable(this.binding.countryCode, "+"), null, null, null); this.binding.country.setOnClickListener(this::onSelectCountryClick); this.binding.next.setOnClickListener(this::onNextClick); setSupportActionBar((Toolbar) this.binding.toolbar); - - this.binding.countryCode.addTextChangedListener(this.countryCodeTextWatcher); - this.region = PhoneNumberUtilWrapper.getUserCountry(this); this.binding.countryCode.setText(String.valueOf(PhoneNumberUtilWrapper.getInstance(this).getCountryCodeForRegion(this.region))); } + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + if (this.region != null) { + savedInstanceState.putString("region", this.region); + } + super.onSaveInstanceState(savedInstanceState); + } + private void onNextClick(View v) { final AlertDialog.Builder builder = new AlertDialog.Builder(this); try { @@ -97,11 +118,25 @@ public class EnterPhoneNumberActivity extends AppCompatActivity { } private void onSelectCountryClick(View view) { - + Intent intent = new Intent(this, ChooseCountryActivity.class); + startActivityForResult(intent, REQUEST_CHOOSE_COUNTRY); } private void onPhoneNumberEntered(Phonenumber.PhoneNumber phoneNumber) { } + @Override + public void onActivityResult(int requestCode, int resultCode, final Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK && requestCode == REQUEST_CHOOSE_COUNTRY) { + String region = data.getStringExtra("region"); + if (region != null) { + this.region = region; + final int countryCode = PhoneNumberUtilWrapper.getInstance(this).getCountryCodeForRegion(region); + this.binding.countryCode.setText(String.valueOf(countryCode)); + } + } + } + } diff --git a/src/quick/java/eu/siacs/conversations/ui/adapter/CountryAdapter.java b/src/quick/java/eu/siacs/conversations/ui/adapter/CountryAdapter.java new file mode 100644 index 000000000..266f9e631 --- /dev/null +++ b/src/quick/java/eu/siacs/conversations/ui/adapter/CountryAdapter.java @@ -0,0 +1,70 @@ +package eu.siacs.conversations.ui.adapter; + +import android.databinding.DataBindingUtil; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import java.util.List; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.databinding.CountryItemBinding; +import eu.siacs.conversations.utils.PhoneNumberUtilWrapper; + +public class CountryAdapter extends RecyclerView.Adapter { + + private final List countries; + + private OnCountryClicked onCountryClicked; + + public CountryAdapter(List countries) { + this.countries = countries; + } + + @NonNull + @Override + public CountryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); + CountryItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.country_item, parent, false); + return new CountryViewHolder(binding); + } + + @Override + public void onBindViewHolder(@NonNull CountryViewHolder holder, int position) { + final PhoneNumberUtilWrapper.Country county = countries.get(position); + holder.binding.country.setText(county.getName()); + holder.binding.countryCode.setText(county.getCode()); + holder.itemView.setOnClickListener(v -> { + if (onCountryClicked != null) { + onCountryClicked.onCountryClicked(county); + } + }); + } + + public void setOnCountryClicked(OnCountryClicked listener) { + this.onCountryClicked = listener; + } + + + @Override + public int getItemCount() { + return countries.size(); + } + + + class CountryViewHolder extends RecyclerView.ViewHolder { + + private final CountryItemBinding binding; + + CountryViewHolder(CountryItemBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } + + public interface OnCountryClicked { + void onCountryClicked(PhoneNumberUtilWrapper.Country country); + } + +} diff --git a/src/quick/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java b/src/quick/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java index 854c0770b..e70aa888d 100644 --- a/src/quick/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java +++ b/src/quick/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java @@ -3,6 +3,8 @@ package eu.siacs.conversations.utils; import android.content.Context; import android.telephony.TelephonyManager; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import io.michaelrocks.libphonenumber.android.PhoneNumberUtil; @@ -50,4 +52,42 @@ public class PhoneNumberUtilWrapper { return localInstance; } + public static List getCountries(final Context context) { + List countries = new ArrayList<>(); + for(String region : getInstance(context).getSupportedRegions()) { + countries.add(new Country(region, getInstance(context).getCountryCodeForRegion(region))); + } + return countries; + + } + + public static class Country implements Comparable { + private final String name; + private final String region; + private final int code; + + Country(String region, int code ) { + this.name = getCountryForCode(region); + this.region = region; + this.code = code; + } + + public String getName() { + return name; + } + + public String getRegion() { + return region; + } + + public String getCode() { + return '+'+String.valueOf(code); + } + + @Override + public int compareTo(Country o) { + return name.compareTo(o.name); + } + } + } diff --git a/src/quick/res/layout/activity_choose_country.xml b/src/quick/res/layout/activity_choose_country.xml new file mode 100644 index 000000000..640923c4f --- /dev/null +++ b/src/quick/res/layout/activity_choose_country.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/quick/res/layout/country_item.xml b/src/quick/res/layout/country_item.xml new file mode 100644 index 000000000..27cf5b320 --- /dev/null +++ b/src/quick/res/layout/country_item.xml @@ -0,0 +1,25 @@ + + + + + + + diff --git a/src/quick/res/menu/choose_country.xml b/src/quick/res/menu/choose_country.xml new file mode 100644 index 000000000..209bb27e0 --- /dev/null +++ b/src/quick/res/menu/choose_country.xml @@ -0,0 +1,11 @@ + + + + +