- Added timezone setting functionality
This commit is contained in:
parent
4d10fc984e
commit
e2a453478c
7 changed files with 190 additions and 29 deletions
|
@ -18,11 +18,14 @@ import android.widget.ArrayAdapter;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Currency;
|
import java.util.Currency;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
@ -32,7 +35,7 @@ import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
import cy.agorise.crystalwallet.enums.Language;
|
import cy.agorise.crystalwallet.enums.Language;
|
||||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||||
|
import cy.agorise.crystalwallet.views.TimeZoneAdapter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,14 +49,18 @@ public class GeneralSettingsFragment extends Fragment {
|
||||||
private LiveData<List<GeneralSetting>> generalSettingListLiveData;
|
private LiveData<List<GeneralSetting>> generalSettingListLiveData;
|
||||||
|
|
||||||
private Boolean spPreferredLanguageInitialized;
|
private Boolean spPreferredLanguageInitialized;
|
||||||
|
private Boolean spTimeZoneInitialized;
|
||||||
|
|
||||||
@BindView (R.id.spTaxableCountry)
|
@BindView (R.id.spTaxableCountry)
|
||||||
Spinner spTaxableCountry;
|
Spinner spTaxableCountry;
|
||||||
@BindView (R.id.spPreferredLanguage)
|
@BindView (R.id.spPreferredLanguage)
|
||||||
Spinner spPreferredLanguage;
|
Spinner spPreferredLanguage;
|
||||||
|
@BindView (R.id.spDisplayDateTime)
|
||||||
|
Spinner spDisplayDateTime;
|
||||||
|
|
||||||
public GeneralSettingsFragment() {
|
public GeneralSettingsFragment() {
|
||||||
this.spPreferredLanguageInitialized = false;
|
this.spPreferredLanguageInitialized = false;
|
||||||
|
this.spTimeZoneInitialized = false;
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +69,7 @@ public class GeneralSettingsFragment extends Fragment {
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
fragment.spPreferredLanguageInitialized = false;
|
fragment.spPreferredLanguageInitialized = false;
|
||||||
|
fragment.spTimeZoneInitialized = false;
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +88,22 @@ public class GeneralSettingsFragment extends Fragment {
|
||||||
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
||||||
generalSettingListLiveData = generalSettingListViewModel.getGeneralSettingList();
|
generalSettingListLiveData = generalSettingListViewModel.getGeneralSettingList();
|
||||||
|
|
||||||
// Initializes the countries spinner
|
|
||||||
|
|
||||||
|
//Observes the general settings data
|
||||||
|
generalSettingListLiveData.observe(this, new Observer<List<GeneralSetting>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(@Nullable List<GeneralSetting> generalSettings) {
|
||||||
|
loadSettings(generalSettings);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initPreferredCountry(GeneralSetting preferredCountrySetting){
|
||||||
countriesMap = new HashMap<String, String>();
|
countriesMap = new HashMap<String, String>();
|
||||||
String[] countryCodeList = Locale.getISOCountries();
|
String[] countryCodeList = Locale.getISOCountries();
|
||||||
ArrayList<String> countryAndCurrencyList = new ArrayList<String>();
|
ArrayList<String> countryAndCurrencyList = new ArrayList<String>();
|
||||||
|
@ -103,23 +125,31 @@ public class GeneralSettingsFragment extends Fragment {
|
||||||
ArrayAdapter<String> countryAdapter = new ArrayAdapter<String>(this.getContext(), android.R.layout.simple_spinner_item, countryAndCurrencyList);
|
ArrayAdapter<String> countryAdapter = new ArrayAdapter<String>(this.getContext(), android.R.layout.simple_spinner_item, countryAndCurrencyList);
|
||||||
spTaxableCountry.setAdapter(countryAdapter);
|
spTaxableCountry.setAdapter(countryAdapter);
|
||||||
|
|
||||||
//Observes the general settings data
|
if (preferredCountrySetting != null) {
|
||||||
generalSettingListLiveData.observe(this, new Observer<List<GeneralSetting>>() {
|
String preferedCountryCode = preferredCountrySetting.getValue();
|
||||||
@Override
|
spTaxableCountry.setSelection(((ArrayAdapter<String>) spTaxableCountry.getAdapter()).getPosition(countriesMap.get(preferedCountryCode)));
|
||||||
public void onChanged(@Nullable List<GeneralSetting> generalSettings) {
|
}
|
||||||
loadSettings(generalSettings);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initPreferredLanguage(GeneralSetting preferredLanguageSetting){
|
public void initPreferredLanguage(GeneralSetting preferredLanguageSetting){
|
||||||
ArrayAdapter<Language> preferredLanguageAdapter = new ArrayAdapter<Language>(getContext(), android.R.layout.simple_spinner_item, Language.values());
|
ArrayAdapter<Language> preferredLanguageAdapter = new ArrayAdapter<Language>(getContext(), android.R.layout.simple_spinner_item, Language.values());
|
||||||
spPreferredLanguage.setAdapter(preferredLanguageAdapter);
|
spPreferredLanguage.setAdapter(preferredLanguageAdapter);
|
||||||
spPreferredLanguage.setSelection(preferredLanguageAdapter.getPosition(Language.getByCode(preferredLanguageSetting.getValue())));
|
if (preferredLanguageSetting != null) {
|
||||||
|
spPreferredLanguage.setSelection(preferredLanguageAdapter.getPosition(Language.getByCode(preferredLanguageSetting.getValue())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initDateTimeFormat(GeneralSetting dateTimeFormatSetting){
|
||||||
|
TimeZoneAdapter timeZoneAdapter;
|
||||||
|
if (spDisplayDateTime.getAdapter() == null) {
|
||||||
|
timeZoneAdapter = new TimeZoneAdapter(getContext(), android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
spDisplayDateTime.setAdapter(timeZoneAdapter);
|
||||||
|
} else {
|
||||||
|
timeZoneAdapter = (TimeZoneAdapter) spDisplayDateTime.getAdapter();
|
||||||
|
}
|
||||||
|
if (dateTimeFormatSetting != null) {
|
||||||
|
spDisplayDateTime.setSelection(timeZoneAdapter.getPosition(dateTimeFormatSetting.getValue()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeneralSetting getSetting(String name){
|
public GeneralSetting getSetting(String name){
|
||||||
|
@ -157,6 +187,27 @@ public class GeneralSettingsFragment extends Fragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnItemSelected(R.id.spDisplayDateTime)
|
||||||
|
void onTimeZoneSelected(int position){
|
||||||
|
//The first call will be when the spinner gets an adapter attached
|
||||||
|
if (this.spTimeZoneInitialized) {
|
||||||
|
String timeZoneIdSelected = (String) this.spDisplayDateTime.getSelectedItem();
|
||||||
|
GeneralSetting generalSettingTimeZone = this.getSetting(GeneralSetting.SETTING_NAME_TIME_ZONE);
|
||||||
|
|
||||||
|
if (generalSettingTimeZone == null) {
|
||||||
|
generalSettingTimeZone = new GeneralSetting();
|
||||||
|
generalSettingTimeZone.setName(GeneralSetting.SETTING_NAME_TIME_ZONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((generalSettingTimeZone.getValue() == null)||(!generalSettingTimeZone.getValue().equals(timeZoneIdSelected))) {
|
||||||
|
generalSettingTimeZone.setValue(timeZoneIdSelected);
|
||||||
|
this.generalSettingListViewModel.saveGeneralSettings(generalSettingTimeZone);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.spTimeZoneInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OnItemSelected(R.id.spPreferredLanguage)
|
@OnItemSelected(R.id.spPreferredLanguage)
|
||||||
void onPreferredLanguageSelected(int position){
|
void onPreferredLanguageSelected(int position){
|
||||||
//The first call will be when the spinner gets an adapter attached
|
//The first call will be when the spinner gets an adapter attached
|
||||||
|
@ -169,7 +220,7 @@ public class GeneralSettingsFragment extends Fragment {
|
||||||
generalSettingPreferredLanguage.setName(GeneralSetting.SETTING_NAME_PREFERRED_LANGUAGE);
|
generalSettingPreferredLanguage.setName(GeneralSetting.SETTING_NAME_PREFERRED_LANGUAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!generalSettingPreferredLanguage.getValue().equals(languageSelected.getCode())) {
|
if ((generalSettingPreferredLanguage.getValue() == null)||(!generalSettingPreferredLanguage.getValue().equals(languageSelected.getCode()))) {
|
||||||
generalSettingPreferredLanguage.setValue(languageSelected.getCode());
|
generalSettingPreferredLanguage.setValue(languageSelected.getCode());
|
||||||
this.generalSettingListViewModel.saveGeneralSettings(generalSettingPreferredLanguage);
|
this.generalSettingListViewModel.saveGeneralSettings(generalSettingPreferredLanguage);
|
||||||
|
|
||||||
|
@ -191,13 +242,9 @@ public class GeneralSettingsFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadSettings(List<GeneralSetting> generalSettings){
|
public void loadSettings(List<GeneralSetting> generalSettings){
|
||||||
for (GeneralSetting generalSetting:generalSettings) {
|
|
||||||
if (generalSetting.getName().equals(GeneralSetting.SETTING_NAME_PREFERRED_COUNTRY)){
|
initPreferredCountry(getSetting(GeneralSetting.SETTING_NAME_PREFERRED_COUNTRY));
|
||||||
String preferedCountryCode = generalSetting.getValue();
|
initPreferredLanguage(getSetting(GeneralSetting.SETTING_NAME_PREFERRED_LANGUAGE));
|
||||||
spTaxableCountry.setSelection(((ArrayAdapter<String>)spTaxableCountry.getAdapter()).getPosition(countriesMap.get(preferedCountryCode)));
|
initDateTimeFormat(getSetting(GeneralSetting.SETTING_NAME_TIME_ZONE));
|
||||||
} else if (generalSetting.getName().equals(GeneralSetting.SETTING_NAME_PREFERRED_LANGUAGE)){
|
|
||||||
initPreferredLanguage(generalSetting);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ public class GeneralSetting {
|
||||||
public final static String SETTING_NAME_PREFERRED_COUNTRY = "PREFERRED_COUNTRY";
|
public final static String SETTING_NAME_PREFERRED_COUNTRY = "PREFERRED_COUNTRY";
|
||||||
public final static String SETTING_NAME_PREFERRED_CURRENCY = "PREFERRED_CURRENCY";
|
public final static String SETTING_NAME_PREFERRED_CURRENCY = "PREFERRED_CURRENCY";
|
||||||
public final static String SETTING_NAME_PREFERRED_LANGUAGE = "PREFERRED_LANGUAGE";
|
public final static String SETTING_NAME_PREFERRED_LANGUAGE = "PREFERRED_LANGUAGE";
|
||||||
|
public final static String SETTING_NAME_TIME_ZONE = "TIME_ZONE";
|
||||||
public final static String SETTING_PASSWORD = "PASSWORD";
|
public final static String SETTING_PASSWORD = "PASSWORD";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,4 +37,8 @@ public class GeneralSettingListViewModel extends AndroidViewModel {
|
||||||
public void saveGeneralSettings(GeneralSetting... generalSettings){
|
public void saveGeneralSettings(GeneralSetting... generalSettings){
|
||||||
this.db.generalSettingDao().insertGeneralSettings(generalSettings);
|
this.db.generalSettingDao().insertGeneralSettings(generalSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GeneralSetting getGeneralSettingByName(String name){
|
||||||
|
return this.db.generalSettingDao().getSettingByName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package cy.agorise.crystalwallet.views;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Henry Varona on 21/3/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TimeZoneAdapter extends ArrayAdapter<String> {
|
||||||
|
|
||||||
|
LayoutInflater inflater;
|
||||||
|
String[] timeZoneIds;
|
||||||
|
|
||||||
|
public TimeZoneAdapter(@NonNull Context context, int resource) {
|
||||||
|
super(context, resource);
|
||||||
|
|
||||||
|
this.inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
this.timeZoneIds = TimeZone.getAvailableIDs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return this.timeZoneIds.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPosition(@Nullable String item) {
|
||||||
|
for (int i=0;i<this.timeZoneIds.length;i++){
|
||||||
|
if (this.timeZoneIds[i].equals(item)){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getItem(int position) {
|
||||||
|
return timeZoneIds[position];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||||
|
String timeZoneId = getItem(position);
|
||||||
|
TimeZone nextTimeZone = TimeZone.getTimeZone(timeZoneId);
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTimeZone(nextTimeZone);
|
||||||
|
long hours = TimeUnit.MILLISECONDS.toHours(nextTimeZone.getRawOffset());
|
||||||
|
long minutes = TimeUnit.MILLISECONDS.toMinutes(nextTimeZone.getRawOffset())
|
||||||
|
- TimeUnit.HOURS.toMinutes(hours);
|
||||||
|
minutes = Math.abs(minutes);
|
||||||
|
String hoursString = (hours > 0?"+"+hours:""+hours);
|
||||||
|
|
||||||
|
View timeZoneItemView = this.inflater.inflate(R.layout.time_zone_spinner_item,null,true);
|
||||||
|
|
||||||
|
TextView tvTimeZoneLabel = (TextView) timeZoneItemView.findViewById(R.id.tvTimeZoneLabel);
|
||||||
|
tvTimeZoneLabel.setText(String.format("%s (GMT%s:%02d)", nextTimeZone.getID(), hoursString, minutes));
|
||||||
|
return timeZoneItemView;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,8 +23,10 @@ import cy.agorise.crystalwallet.activities.CryptoCoinTransactionReceiptActivity;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
|
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCurrency;
|
import cy.agorise.crystalwallet.models.CryptoCurrency;
|
||||||
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
import cy.agorise.crystalwallet.viewmodels.CryptoCurrencyViewModel;
|
import cy.agorise.crystalwallet.viewmodels.CryptoCurrencyViewModel;
|
||||||
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel;
|
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel;
|
||||||
|
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Henry Varona on 17/9/2017.
|
* Created by Henry Varona on 17/9/2017.
|
||||||
|
@ -122,13 +124,23 @@ public class TransactionViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
String amountString = String.format("%.2f",transaction.getAmount()/Math.pow(10,cryptoCurrency.getPrecision()));
|
String amountString = String.format("%.2f",transaction.getAmount()/Math.pow(10,cryptoCurrency.getPrecision()));
|
||||||
|
|
||||||
|
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this.fragment).get(GeneralSettingListViewModel.class);
|
||||||
|
GeneralSetting timeZoneSetting = generalSettingListViewModel.getGeneralSettingByName(GeneralSetting.SETTING_NAME_TIME_ZONE);
|
||||||
|
|
||||||
|
TimeZone userTimeZone;
|
||||||
|
if (timeZoneSetting != null){
|
||||||
|
userTimeZone = TimeZone.getTimeZone(timeZoneSetting.getValue());
|
||||||
|
} else {
|
||||||
|
userTimeZone = TimeZone.getTimeZone("cet");
|
||||||
|
}
|
||||||
|
|
||||||
DateFormat dateFormat = new SimpleDateFormat("dd MMM");
|
DateFormat dateFormat = new SimpleDateFormat("dd MMM");
|
||||||
dateFormat.setTimeZone(TimeZone.getTimeZone("cet"));
|
dateFormat.setTimeZone(userTimeZone);
|
||||||
DateFormat hourFormat = new SimpleDateFormat("HH:mm:ss");
|
DateFormat hourFormat = new SimpleDateFormat("HH:mm:ss");
|
||||||
hourFormat.setTimeZone(TimeZone.getTimeZone("cet"));
|
hourFormat.setTimeZone(userTimeZone);
|
||||||
|
|
||||||
tvTransactionDate.setText(dateFormat.format(transaction.getDate()));
|
tvTransactionDate.setText(dateFormat.format(transaction.getDate()));
|
||||||
tvTransactionHour.setText(hourFormat.format(transaction.getDate())+" CET");
|
tvTransactionHour.setText(hourFormat.format(transaction.getDate()));
|
||||||
|
|
||||||
tvFrom.setText(transaction.getFrom());
|
tvFrom.setText(transaction.getFrom());
|
||||||
tvTo.setText(transaction.getTo());
|
tvTo.setText(transaction.getTo());
|
||||||
|
|
|
@ -112,9 +112,9 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvDisplayDateTime"
|
app:layout_constraintEnd_toEndOf="@id/spPreferredLanguage"
|
||||||
app:layout_constraintStart_toStartOf="@id/spPreferredLanguage"
|
app:layout_constraintStart_toStartOf="@id/spPreferredLanguage"
|
||||||
app:layout_constraintEnd_toEndOf="@id/spPreferredLanguage"/>
|
app:layout_constraintTop_toBottomOf="@id/tvDisplayDateTime" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/vDisplayDateTime"
|
android:id="@+id/vDisplayDateTime"
|
||||||
|
|
24
app/src/main/res/layout/time_zone_spinner_item.xml
Normal file
24
app/src/main/res/layout/time_zone_spinner_item.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:paddingTop="10dp">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvTimeZoneLabel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
Loading…
Reference in a new issue