Changes from Alpha Feedback (#113)

* fab covers whole screen

* avoid potential NPE

* bugfix - spinners crashed after scan

* Gunther only if no wallets

* clearQR on failed exchange, tweaks, gray

* refactor info dialogs

* added default testnet node

* FAQ: my testnet wallet is broken

* version code 36, version name 1.1.7
This commit is contained in:
m2049r 2017-11-04 10:17:20 +01:00 committed by GitHub
parent d67e02cbcb
commit 545367db90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 136 additions and 172 deletions

View File

@ -8,8 +8,8 @@ android {
applicationId "com.m2049r.xmrwallet" applicationId "com.m2049r.xmrwallet"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 25 targetSdkVersion 25
versionCode 34 versionCode 36
versionName "1.1.6" versionName "1.1.7"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild { externalNativeBuild {
cmake { cmake {

View File

@ -1054,22 +1054,22 @@ public class LoginActivity extends AppCompatActivity
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_create_help_new: case R.id.action_create_help_new:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_create_new); HelpFragment.display(getSupportFragmentManager(), R.string.help_create_new);
return true; return true;
case R.id.action_create_help_keys: case R.id.action_create_help_keys:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_create_keys); HelpFragment.display(getSupportFragmentManager(), R.string.help_create_keys);
return true; return true;
case R.id.action_create_help_view: case R.id.action_create_help_view:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_create_view); HelpFragment.display(getSupportFragmentManager(), R.string.help_create_view);
return true; return true;
case R.id.action_create_help_seed: case R.id.action_create_help_seed:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_create_seed); HelpFragment.display(getSupportFragmentManager(), R.string.help_create_seed);
return true; return true;
case R.id.action_details_help: case R.id.action_details_help:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_details); HelpFragment.display(getSupportFragmentManager(), R.string.help_details);
return true; return true;
case R.id.action_license_info: case R.id.action_license_info:
AboutFragment.displayHelp(getSupportFragmentManager(), R.string.about_licenses); AboutFragment.display(getSupportFragmentManager());
return true; return true;
case R.id.action_privacy_policy: case R.id.action_privacy_policy:
PrivacyFragment.display(getSupportFragmentManager()); PrivacyFragment.display(getSupportFragmentManager());

View File

@ -65,6 +65,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
List<WalletManager.WalletInfo> displayedList = new ArrayList<>(); List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
EditText etDummy; EditText etDummy;
ImageView ivGunther;
DropDownEditText etDaemonAddress; DropDownEditText etDaemonAddress;
ArrayAdapter<String> nodeAdapter; ArrayAdapter<String> nodeAdapter;
@ -131,6 +132,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
Log.d(TAG, "onCreateView"); Log.d(TAG, "onCreateView");
View view = inflater.inflate(R.layout.fragment_login, container, false); View view = inflater.inflate(R.layout.fragment_login, container, false);
ivGunther = (ImageView) view.findViewById(R.id.ivGunther);
fabScreen = (FrameLayout) view.findViewById(R.id.fabScreen); fabScreen = (FrameLayout) view.findViewById(R.id.fabScreen);
fab = (FloatingActionButton) view.findViewById(R.id.fab); fab = (FloatingActionButton) view.findViewById(R.id.fab);
fabNew = (FloatingActionButton) view.findViewById(R.id.fabNew); fabNew = (FloatingActionButton) view.findViewById(R.id.fabNew);
@ -269,10 +271,18 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
filterList(); filterList();
adapter.setInfos(displayedList); adapter.setInfos(displayedList);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
// deal with Gunther & FAB animation
if (displayedList.isEmpty()) { if (displayedList.isEmpty()) {
fab.startAnimation(fab_pulse); fab.startAnimation(fab_pulse);
if (ivGunther.getDrawable() == null) {
ivGunther.setImageResource(R.drawable.gunther_desaturated);
}
} else { } else {
fab.clearAnimation(); fab.clearAnimation();
if (ivGunther.getDrawable() != null) {
ivGunther.setImageDrawable(null);
}
} }
} }
@ -329,7 +339,10 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
//private static final String PREF_TESTNET = "testnet"; //private static final String PREF_TESTNET = "testnet";
private static final String PREF_DAEMONLIST_MAINNET = private static final String PREF_DAEMONLIST_MAINNET =
"node.moneroworld.com:18089;node.xmrbackb.one:18081;node.xmr.be:18081"; "node.moneroworld.com:18089;node.xmrbackb.one;node.xmr.be";
private static final String PREF_DAEMONLIST_TESTNET =
"testnet.xmrchain.net";
private NodeList daemonTestNet; private NodeList daemonTestNet;
private NodeList daemonMainNet; private NodeList daemonMainNet;
@ -338,7 +351,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
SharedPreferences sharedPref = activityCallback.getPrefs(); SharedPreferences sharedPref = activityCallback.getPrefs();
daemonMainNet = new NodeList(sharedPref.getString(PREF_DAEMON_MAINNET, PREF_DAEMONLIST_MAINNET)); daemonMainNet = new NodeList(sharedPref.getString(PREF_DAEMON_MAINNET, PREF_DAEMONLIST_MAINNET));
daemonTestNet = new NodeList(sharedPref.getString(PREF_DAEMON_TESTNET, "")); daemonTestNet = new NodeList(sharedPref.getString(PREF_DAEMON_TESTNET, PREF_DAEMONLIST_TESTNET));
setNet(isTestnet(), false); setNet(isTestnet(), false);
} }

View File

@ -116,6 +116,7 @@ public class ReceiveFragment extends Fragment {
evAmount.setOnFailedExchangeListener(new ExchangeView.OnFailedExchangeListener() { evAmount.setOnFailedExchangeListener(new ExchangeView.OnFailedExchangeListener() {
@Override @Override
public void onFailedExchange() { public void onFailedExchange() {
clearQR();
Toast.makeText(getActivity(), getString(R.string.message_exchange_failed), Toast.LENGTH_LONG).show(); Toast.makeText(getActivity(), getString(R.string.message_exchange_failed), Toast.LENGTH_LONG).show();
} }
}); });

View File

@ -227,8 +227,13 @@ public class SendFragment extends Fragment {
sMixin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { sMixin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) { public void onItemSelected(final AdapterView<?> parentView, View selectedItemView, int position, long id) {
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray)); parentView.post(new Runnable() {
@Override
public void run() {
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray));
}
});
} }
@Override @Override
@ -238,8 +243,13 @@ public class SendFragment extends Fragment {
}); });
sPriority.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { sPriority.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) { public void onItemSelected(final AdapterView<?> parentView, View selectedItemView, int position, long id) {
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray)); parentView.post(new Runnable() {
@Override
public void run() {
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray));
}
});
} }
@Override @Override

View File

@ -44,7 +44,6 @@ import com.m2049r.xmrwallet.model.TransactionInfo;
import com.m2049r.xmrwallet.model.Wallet; import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager; import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.service.WalletService; import com.m2049r.xmrwallet.service.WalletService;
import com.m2049r.xmrwallet.util.AsyncExchangeRate;
import com.m2049r.xmrwallet.util.BarcodeData; import com.m2049r.xmrwallet.util.BarcodeData;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.TxData; import com.m2049r.xmrwallet.util.TxData;
@ -162,10 +161,10 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
onShareTxInfo(); onShareTxInfo();
return true; return true;
case R.id.action_help_tx_info: case R.id.action_help_tx_info:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_tx_details); HelpFragment.display(getSupportFragmentManager(), R.string.help_tx_details);
return true; return true;
case R.id.action_help_sync: case R.id.action_help_sync:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_sync); HelpFragment.display(getSupportFragmentManager(), R.string.help_sync);
return true; return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);

View File

@ -33,43 +33,27 @@ import com.m2049r.xmrwallet.BuildConfig;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;
public class AboutFragment extends DialogFragment { public class AboutFragment extends DialogFragment {
static final String TAG = "HelpFragment"; static final String TAG = "AboutFragment";
private static final String HELP_ID = "HELP_ID";
public static AboutFragment newInstance(int helpResourceId) { public static AboutFragment newInstance() {
AboutFragment fragment = new AboutFragment(); return new AboutFragment();
Bundle bundle = new Bundle();
bundle.putInt(HELP_ID, helpResourceId);
fragment.setArguments(bundle);
return fragment;
} }
public static void displayHelp(FragmentManager fm, int helpResourceId) { public static void display(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction(); FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(TAG); Fragment prev = fm.findFragmentByTag(TAG);
if (prev != null) { if (prev != null) {
ft.remove(prev); ft.remove(prev);
} }
DialogFragment helpFragment = AboutFragment.newInstance(helpResourceId); AboutFragment.newInstance().show(ft, TAG);
helpFragment.show(ft, TAG);
} }
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_about, null); final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_about, null);
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getString(R.string.about_licenses)));
int helpId = 0; ((TextView) view.findViewById(R.id.tvVersion)).setText(getString(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE));
Bundle arguments = getArguments();
if (arguments != null) {
helpId = arguments.getInt(HELP_ID);
}
if (helpId > 0) {
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getString(helpId)));
}
TextView text = (TextView) view.findViewById(R.id.tvVersion);
text.setText(getString(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE));
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view); builder.setView(view);

View File

@ -14,82 +14,49 @@
* limitations under the License. * limitations under the License.
*/ */
/**
* Based on work by Adam Speakman http://speakman.net.nz
*/
package com.m2049r.xmrwallet.dialog; package com.m2049r.xmrwallet.dialog;
import android.annotation.SuppressLint;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.text.Html; import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.webkit.WebView;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.m2049r.xmrwallet.BuildConfig;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class DonationFragment extends DialogFragment { public class DonationFragment extends DialogFragment {
static final String TAG = "DonationFragment"; static final String TAG = "DonationFragment";
private static final String FRAGMENT_TAG = "com.m2049r.xmrwalelt.dialog.DonationFragment";
/**
* Creates a new instance of LicensesFragment with no Close button.
*
* @return A new licenses fragment.
*/
public static DonationFragment newInstance() { public static DonationFragment newInstance() {
return new DonationFragment(); return new DonationFragment();
} }
/**
* Builds and displays a licenses fragment with no Close button. Requires
* "/res/raw/licenses.html" and "/res/layout/licenses_fragment.xml" to be
* present.
*
* @param fm A fragment manager instance used to display this LicensesFragment.
*/
public static void display(FragmentManager fm) { public static void display(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction(); FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(FRAGMENT_TAG); Fragment prev = fm.findFragmentByTag(TAG);
if (prev != null) { if (prev != null) {
ft.remove(prev); ft.remove(prev);
} }
ft.addToBackStack(null);
// Create and show the dialog. DonationFragment.newInstance().show(ft, TAG);
DialogFragment newFragment = DonationFragment.newInstance();
newFragment.show(ft, FRAGMENT_TAG);
} }
@SuppressLint("InflateParams")
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_donation, null); final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_donation, null);
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.donation_credits))); ((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.donation_credits)));
((ImageButton) view.findViewById(R.id.bCopyAddress)). (view.findViewById(R.id.bCopyAddress)).
setOnClickListener(new View.OnClickListener() { setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {

View File

@ -43,15 +43,14 @@ public class HelpFragment extends DialogFragment {
return fragment; return fragment;
} }
public static void displayHelp(FragmentManager fm, int helpResourceId) { public static void display(FragmentManager fm, int helpResourceId) {
FragmentTransaction ft = fm.beginTransaction(); FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(TAG); Fragment prev = fm.findFragmentByTag(TAG);
if (prev != null) { if (prev != null) {
ft.remove(prev); ft.remove(prev);
} }
DialogFragment helpFragment = HelpFragment.newInstance(helpResourceId); HelpFragment.newInstance(helpResourceId).show(ft, TAG);
helpFragment.show(ft, TAG);
} }
@Override @Override

View File

@ -14,13 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
/**
* Based on work by Adam Speakman http://speakman.net.nz
*/
package com.m2049r.xmrwallet.dialog; package com.m2049r.xmrwallet.dialog;
import android.annotation.SuppressLint;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -32,47 +27,27 @@ import android.support.v4.app.FragmentTransaction;
import android.text.Html; import android.text.Html;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.util.Helper;
public class PrivacyFragment extends DialogFragment { public class PrivacyFragment extends DialogFragment {
static final String TAG = "PrivacyFragment"; static final String TAG = "PrivacyFragment";
private static final String FRAGMENT_TAG = "com.m2049r.xmrwalelt.dialog.PrivacyFragment";
/**
* Creates a new instance of LicensesFragment with no Close button.
*
* @return A new licenses fragment.
*/
public static PrivacyFragment newInstance() { public static PrivacyFragment newInstance() {
return new PrivacyFragment(); return new PrivacyFragment();
} }
/**
* Builds and displays a licenses fragment with no Close button. Requires
* "/res/raw/licenses.html" and "/res/layout/licenses_fragment.xml" to be
* present.
*
* @param fm A fragment manager instance used to display this LicensesFragment.
*/
public static void display(FragmentManager fm) { public static void display(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction(); FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(FRAGMENT_TAG); Fragment prev = fm.findFragmentByTag(TAG);
if (prev != null) { if (prev != null) {
ft.remove(prev); ft.remove(prev);
} }
ft.addToBackStack(null);
// Create and show the dialog. PrivacyFragment.newInstance().show(ft, TAG);
DialogFragment newFragment = PrivacyFragment.newInstance();
newFragment.show(ft, FRAGMENT_TAG);
} }
@SuppressLint("InflateParams")
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_privacy_policy, null); final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_privacy_policy, null);

View File

@ -179,11 +179,16 @@ public class ExchangeView extends LinearLayout implements AsyncExchangeRate.List
sCurrencyB.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { sCurrencyB.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) { public void onItemSelected(final AdapterView<?> parentView, View selectedItemView, int position, long id) {
if (position != 0) { // if not XMR, select XMR on other if (position != 0) { // if not XMR, select XMR on other
sCurrencyA.setSelection(0, true); sCurrencyA.setSelection(0, true);
} }
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray)); parentView.post(new Runnable() {
@Override
public void run() {
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray));
}
});
doExchange(); doExchange();
} }

View File

@ -333,7 +333,8 @@ public class WalletService extends Service {
Wallet myWallet = getWallet(); Wallet myWallet = getWallet();
Log.d(TAG, "SEND TX for wallet: " + myWallet.getName()); Log.d(TAG, "SEND TX for wallet: " + myWallet.getName());
PendingTransaction pendingTransaction = myWallet.getPendingTransaction(); PendingTransaction pendingTransaction = myWallet.getPendingTransaction();
if (pendingTransaction.getStatus() != PendingTransaction.Status.Status_Ok) { if ((pendingTransaction == null)
|| (pendingTransaction.getStatus() != PendingTransaction.Status.Status_Ok)) {
Log.e(TAG, "PendingTransaction is " + pendingTransaction.getStatus()); Log.e(TAG, "PendingTransaction is " + pendingTransaction.getStatus());
myWallet.disposePendingTransaction(); // it's broken anyway myWallet.disposePendingTransaction(); // it's broken anyway
if (observer != null) observer.onSentTransaction(false); if (observer != null) observer.onSentTransaction(false);

View File

@ -1,70 +1,76 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_margin="8sp" android:layout_margin="8sp">
android:orientation="vertical">
<EditText <LinearLayout
android:id="@+id/etDummy"
android:layout_width="0dp"
android:layout_height="0dp" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_margin="16dp" android:orientation="vertical">
android:hint="@string/label_daemon">
<com.m2049r.xmrwallet.layout.DropDownEditText <EditText
android:id="@+id/etDaemonAddress" android:id="@+id/etDummy"
style="@style/MoneroEdit.Small" android:layout_width="0dp"
android:layout_height="0dp" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="start" android:layout_margin="16dp"
android:hint="@string/prompt_daemon" android:hint="@string/label_daemon">
android:imeOptions="actionDone"
android:inputType="textWebEmailAddress|textNoSuggestions"
android:maxLines="1"
android:textIsSelectable="true" />
</android.support.design.widget.TextInputLayout>
<TextView <com.m2049r.xmrwallet.layout.DropDownEditText
style="@style/MoneroLabel.Heading" android:id="@+id/etDaemonAddress"
android:layout_width="match_parent" style="@style/MoneroEdit.Small"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:gravity="center" android:layout_height="wrap_content"
android:padding="8sp" android:gravity="start"
android:text="@string/label_login_wallets" /> android:hint="@string/prompt_daemon"
android:imeOptions="actionDone"
android:inputType="textWebEmailAddress|textNoSuggestions"
android:maxLines="1"
android:textIsSelectable="true" />
</android.support.design.widget.TextInputLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <TextView
xmlns:app="http://schemas.android.com/apk/res-auto" style="@style/MoneroLabel.Heading"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:fillViewport="true"> android:gravity="center"
android:padding="8sp"
android:text="@string/label_login_wallets" />
<ImageView <FrameLayout 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="match_parent">
<ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:adjustViewBounds="true" android:fillViewport="true">
android:padding="48dp"
android:src="@drawable/gunther_desaturated" />
</ScrollView>
<android.support.v7.widget.RecyclerView xmlns:tools="http://schemas.android.com/tools" <ImageView
android:id="@+id/list" android:id="@+id/ivGunther"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:adjustViewBounds="true"
android:paddingBottom="72dp" android:padding="48dp" />
app:layoutManager="LinearLayoutManager" </ScrollView>
tools:listitem="@layout/item_wallet" />
<include layout="@layout/layout_fabmenu" /> <android.support.v7.widget.RecyclerView xmlns:tools="http://schemas.android.com/tools"
</FrameLayout> android:id="@+id/list"
</LinearLayout> android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="72dp"
app:layoutManager="LinearLayoutManager"
tools:listitem="@layout/item_wallet" />
</FrameLayout>
</LinearLayout>
<include layout="@layout/layout_fabmenu" />
</FrameLayout>

View File

@ -75,6 +75,7 @@
style="@style/MoneroEdit" style="@style/MoneroEdit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:backgroundTint="@color/moneroGray"
android:hint="@string/receive_paymentid_hint" android:hint="@string/receive_paymentid_hint"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:inputType="textMultiLine" android:inputType="textMultiLine"

View File

@ -12,11 +12,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<EditText
android:id="@+id/etDummy"
android:layout_width="0sp"
android:layout_height="0sp" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -85,9 +80,9 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="10" android:layout_weight="10"
android:backgroundTint="@color/moneroGray"
android:hint="@string/send_paymentid_hint" android:hint="@string/send_paymentid_hint"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:backgroundTint="@color/moneroGray"
android:inputType="textMultiLine" android:inputType="textMultiLine"
android:textAlignment="textStart" /> android:textAlignment="textStart" />
</android.support.design.widget.TextInputLayout> </android.support.design.widget.TextInputLayout>
@ -105,6 +100,11 @@
android:textColor="@color/moneroGray" /> android:textColor="@color/moneroGray" />
</LinearLayout> </LinearLayout>
<EditText
android:id="@+id/etDummy"
android:layout_width="0sp"
android:layout_height="0sp" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -27,10 +27,13 @@
- Archive (=Backup and delete) - Archive (=Backup and delete)
- 3 Default nodes + History of last 5 used nodes - 3 Default nodes + History of last 5 used nodes
## After installing from Google Play the wallet list is empty! ## My new testnet wallet does not update
Sorry about that. The folder for the wallets was renamed from "Monerujo" to "monerujo". Since testnet block times are very variable, the algorithm calculating block height does not
On most devices this does not matter (they don't care about upper/lower case). Yours does. produce good results - so in general you testnet wallet will not work out of the box.
If you use a file explorer (e.g. es file explorer) you can find the Monerujo folder and rename it to "monerujo".
The remedy is simple: restore from seed and the correct / current block height. Take the block number
of your first transaction or the current block height from the
[Testnet Blockchain Explorer](https://testnet.xmrchain.com/).
## I cannot select and copy the mnemonic seed ## I cannot select and copy the mnemonic seed
Copying anything to the clipboard on Android exposes it to any other App running. So this Copying anything to the clipboard on Android exposes it to any other App running. So this