Improved password + QuickUnlock screens by introducing AdjustResize (now working with design lib 22.2.1.0)

This commit is contained in:
Philipp Crocoll 2015-09-15 21:45:04 +02:00
parent b856e1ec15
commit cc47c71059
9 changed files with 650 additions and 454 deletions

View File

@ -0,0 +1,88 @@
using System;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Util;
namespace keepass2android
{
public class FixedDrawerLayout : Android.Support.V4.Widget.DrawerLayout
{
private bool _fitsSystemWindows;
protected FixedDrawerLayout(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
public FixedDrawerLayout(Context context, IAttributeSet attrs, int defStyle)
: base(context, attrs, defStyle)
{
}
public FixedDrawerLayout(Context context, IAttributeSet attrs)
: base(context, attrs)
{
}
public FixedDrawerLayout(Context context)
: base(context)
{
}
private int[] mInsets = new int[4];
protected override bool FitSystemWindows(Rect insets)
{
if (Build.VERSION.SdkInt >= Build.VERSION_CODES.Kitkat)
{
// Intentionally do not modify the bottom inset. For some reason,
// if the bottom inset is modified, window resizing stops working.
// TODO: Figure out why.
mInsets[0] = insets.Left;
mInsets[1] = insets.Top;
mInsets[2] = insets.Right;
insets.Left = 0;
insets.Top = 0;
insets.Right = 0;
}
return base.FitSystemWindows(insets);
}
public int[] GetInsets()
{
return mInsets;
}
public struct MeasureArgs
{
public int ActualHeight;
public int ProposedHeight;
}
public event EventHandler<MeasureArgs> MeasureEvent;
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
MeasureArgs args;
args.ProposedHeight = MeasureSpec.GetSize(heightMeasureSpec);
args.ActualHeight = Height;
OnMeasureEvent(args);
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}
protected virtual void OnMeasureEvent(MeasureArgs args)
{
var handler = MeasureEvent;
if (handler != null) handler(this, args);
}
}
}

View File

@ -0,0 +1,64 @@
using System;
using Android.Content;
using Android.Runtime;
using Android.Util;
using Android.Widget;
namespace keepass2android
{
public class MeasuringRelativeLayout : RelativeLayout
{
protected MeasuringRelativeLayout(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
public MeasuringRelativeLayout(Context context)
: base(context)
{
}
public MeasuringRelativeLayout(Context context, IAttributeSet attrs)
: base(context, attrs)
{
}
public MeasuringRelativeLayout(Context context, IAttributeSet attrs, int defStyleAttr)
: base(context, attrs, defStyleAttr)
{
}
public MeasuringRelativeLayout(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes)
: base(context, attrs, defStyleAttr, defStyleRes)
{
}
public class MeasureArgs
{
public int ActualHeight;
public int ProposedHeight;
}
public event EventHandler<MeasureArgs> MeasureEvent;
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
MeasureArgs args = new MeasureArgs();
args.ProposedHeight = MeasureSpec.GetSize(heightMeasureSpec);
args.ActualHeight = Height;
OnMeasureEvent(args);
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}
protected virtual void OnMeasureEvent(MeasureArgs args)
{
var handler = MeasureEvent;
if (handler != null) handler(this, args);
}
}
}

View File

@ -38,7 +38,6 @@ using Android.Graphics;
using Android.Support.Design.Widget;
using Android.Support.V4.Widget;
using Android.Support.V7.App;
using Android.Util;
using keepass2android;
using KeePassLib.Keys;
using KeePassLib.Serialization;
@ -56,13 +55,15 @@ using Process = Android.OS.Process;
using KeeChallenge;
using AlertDialog = Android.App.AlertDialog;
using Toolbar = Android.Support.V7.Widget.Toolbar;
namespace keepass2android
{
[Activity(Label = "@string/app_name",
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
ConfigurationChanges = ConfigChanges.Orientation,
LaunchMode = LaunchMode.SingleInstance,
Theme = "@style/MyTheme_Blue")] /*caution: also contained in AndroidManifest.xml*/
WindowSoftInputMode = SoftInput.AdjustResize,
Theme = "@style/MyTheme_Blue")] /*caution: also contained in AndroidManifest.xml*/
//TODO: rotating device crashes the app
public class PasswordActivity : LockingActivity {
@ -149,7 +150,6 @@ namespace keepass2android
private const string KeyFileOrProviderKey = "KeyFileOrProviderKey";
private ActivityDesign _design;
private bool _performingLoad;
private bool _keepPasswordInOnResume;
private Typeface _passwordFont;
@ -161,12 +161,12 @@ namespace keepass2android
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
_design = new ActivityDesign(this);
}
public PasswordActivity()
{
_design = new ActivityDesign(this);
}
@ -680,11 +680,68 @@ namespace keepass2android
}
}
int count = 1;
private DrawerLayout mDrawerLayout;
//private RecyclerView mDrawerList;
private string mDrawerTitle;
private MeasuringRelativeLayout.MeasureArgs _measureArgs;
internal class MyActionBarDrawerToggle : ActionBarDrawerToggle
{
PasswordActivity owner;
public MyActionBarDrawerToggle(PasswordActivity activity, DrawerLayout layout, int imgRes, int openRes, int closeRes)
: base(activity, layout, openRes, closeRes)
{
owner = activity;
}
public override void OnDrawerClosed(View drawerView)
{
owner.SupportActionBar.Title = owner.Title;
owner.InvalidateOptionsMenu();
}
public override void OnDrawerOpened(View drawerView)
{
owner.SupportActionBar.Title = owner.mDrawerTitle;
owner.InvalidateOptionsMenu();
}
}
private void UncollapseToolbar()
{
AppBarLayout appbarLayout = FindViewById<AppBarLayout>(Resource.Id.appbar);
var tmp = appbarLayout.LayoutParameters;
CoordinatorLayout.LayoutParams p = tmp.JavaCast<CoordinatorLayout.LayoutParams>();
var tmp2 = p.Behavior;
var behavior = tmp2.JavaCast<AppBarLayout.Behavior>();
if (behavior == null)
{
p.Behavior = behavior = new AppBarLayout.Behavior();
}
behavior.OnNestedFling(FindViewById<CoordinatorLayout>(Resource.Id.main_content), appbarLayout, null, 0, -10000, false);
}
private void CollapseToolbar()
{
AppBarLayout appbarLayout = FindViewById<AppBarLayout>(Resource.Id.appbar);
ViewGroup.LayoutParams tmp = appbarLayout.LayoutParameters;
CoordinatorLayout.LayoutParams p = tmp.JavaCast<CoordinatorLayout.LayoutParams>();
var tmp2 = p.Behavior;
var behavior = tmp2.JavaCast<AppBarLayout.Behavior>();
if (behavior == null)
{
p.Behavior = behavior = new AppBarLayout.Behavior();
}
behavior.OnNestedFling(FindViewById<CoordinatorLayout>(Resource.Id.main_content), appbarLayout, null, 0, 200, true);
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
_design.ApplyTheme();
//use FlagSecure to make sure the last (revealed) character of the master password is not visible in recent apps
if (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(
GetString(Resource.String.ViewDatabaseSecure_key), true))
@ -692,7 +749,6 @@ namespace keepass2android
Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);
}
Intent i = Intent;
//only load the AppTask if this is the "first" OnCreate (not because of kill/resume, i.e. savedInstanceState==null)
@ -705,12 +761,12 @@ namespace keepass2android
}
else
{
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
}
String action = i.Action;
_prefs = PreferenceManager.GetDefaultSharedPreferences(this);
_rememberKeyfile = _prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default));
@ -720,7 +776,7 @@ namespace keepass2android
if (action != null && action.Equals(ViewIntent))
{
if (!GetIocFromViewIntent(i)) return;
}
}
else if ((action != null) && (action.Equals(Intents.StartWithOtp)))
{
if (!GetIocFromOtpIntent(savedInstanceState, i)) return;
@ -758,56 +814,49 @@ namespace keepass2android
App.Kp2a.LockDatabase(false);
}
SetContentView(Resource.Layout.password);
InitializeToolbar();
InitializeToolbar();
InitializeFilenameView();
InitializeFilenameView();
if (KeyProviderType == KeyProviders.KeyFile)
{
UpdateKeyfileIocView();
}
var passwordEdit = FindViewById<EditText>(Resource.Id.password_edit);
passwordEdit.TextChanged +=
var passwordEdit = FindViewById<EditText>(Resource.Id.password_edit);
passwordEdit.TextChanged +=
(sender, args) =>
{
_password = passwordEdit.Text;
UpdateOkButtonState();
};
passwordEdit.EditorAction += (sender, args) =>
{
if ((args.ActionId == ImeAction.Done) || ((args.ActionId == ImeAction.ImeNull) && (args.Event.Action == KeyEventActions.Down)))
OnOk();
};
{
if ((args.ActionId == ImeAction.Done) || ((args.ActionId == ImeAction.ImeNull) && (args.Event.Action == KeyEventActions.Down)))
OnOk();
};
FindViewById<EditText>(Resource.Id.pass_otpsecret).TextChanged += (sender, args) => UpdateOkButtonState();
passwordEdit.Text = _password;
passwordEdit.RequestFocus();
Window.SetSoftInputMode(SoftInput.StateVisible);
var passwordFont = Typeface.CreateFromAsset(Assets, "SourceCodePro-Regular.ttf");
passwordEdit.Typeface = passwordFont;
InitializeBottomBarButtons();
InitializePasswordModeSpinner();
InitializeOtpSecretSpinner();
InitializeNavDrawerButtons();
InitializeNavDrawerButtons();
UpdateOkButtonState();
InitializeTogglePasswordButton();
InitializeKeyfileBrowseButton();
@ -821,6 +870,30 @@ namespace keepass2android
.PrepareFileUsage(new FileStorageSetupInitiatorActivity(this, OnActivityResult, null), _ioConnection,
RequestCodePrepareDbFile, false);
}
mDrawerTitle = this.Title;
mDrawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
var rootview = FindViewById<MeasuringRelativeLayout>(Resource.Id.relative_layout);
rootview.ViewTreeObserver.GlobalLayout += (sender, args2) =>
{
Android.Util.Log.Debug("KP2A", "GlobalLayout");
var args = _measureArgs;
if (args == null)
return;
Android.Util.Log.Debug("KP2A", "ActualHeight=" + args.ActualHeight);
Android.Util.Log.Debug("KP2A", "ProposedHeight=" + args.ProposedHeight);
if (args.ActualHeight < args.ProposedHeight)
UncollapseToolbar();
if (args.ActualHeight > args.ProposedHeight)
CollapseToolbar();
};
rootview.MeasureEvent += (sender, args) =>
{
//Snackbar.Make(rootview, "height="+args.ActualHeight, Snackbar.LengthLong).Show();
this._measureArgs = args;
};
}
private void InitializeNavDrawerButtons()
@ -1436,7 +1509,7 @@ namespace keepass2android
outState.PutString(OtpInfoKey, sw.ToString());
}
//more OTP TODO:
// * Caching of aux file
// * -> implement IFileStorage in JavaFileStorage based on ListFiles
@ -1507,7 +1580,12 @@ namespace keepass2android
{
base.OnResume();
_design.ReapplyTheme();
EditText pwd = FindViewById<EditText>(Resource.Id.password_edit);
pwd.PostDelayed(() =>
{
InputMethodManager keyboard = (InputMethodManager)GetSystemService(Context.InputMethodService);
keyboard.ShowSoftInput(pwd, 0);
}, 50);
View killButton = FindViewById(Resource.Id.kill_app);
if (PreferenceManager.GetDefaultSharedPreferences(this)
@ -1526,7 +1604,7 @@ namespace keepass2android
{
killButton.Visibility = ViewStates.Gone;
}
if (!_keepPasswordInOnResume)
{
if (

View File

@ -54,7 +54,7 @@
</intent-filter>
</activity>
<activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<activity android:configChanges="orientation" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />

View File

@ -57,7 +57,7 @@
</intent-filter>
</activity>
<activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:theme="@style/MyTheme" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<activity android:configChanges="orientation" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />

View File

@ -24,30 +24,31 @@ using Android.Widget;
using Android.Content.PM;
using KeePassLib.Keys;
using Android.Preferences;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Views.InputMethods;
using KeePassLib.Serialization;
namespace keepass2android
{
[Activity(Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
[Activity(Label = "@string/app_name",
ConfigurationChanges = ConfigChanges.Orientation,
WindowSoftInputMode = SoftInput.AdjustResize,
MainLauncher = false,
Theme = "@style/MyTheme_Blue")]
public class QuickUnlock : LifecycleDebugActivity
{
private IOConnectionInfo _ioc;
private QuickUnlockBroadcastReceiver _intentReceiver;
private ActivityDesign _design;
public QuickUnlock()
{
_design = new ActivityDesign(this);
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
_design.ApplyTheme();
//use FlagSecure to make sure the last (revealed) character of the password is not visible in recent apps
if (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(
GetString(Resource.String.ViewDatabaseSecure_key), true))
@ -63,9 +64,8 @@ namespace keepass2android
return;
}
SetContentView(Resource.Layout.QuickUnlock);
if (App.Kp2a.GetDb().KpDatabase.Name != "")
{
FindViewById(Resource.Id.filename_label).Visibility = ViewStates.Visible;
@ -122,8 +122,10 @@ namespace keepass2android
IntentFilter filter = new IntentFilter();
filter.AddAction(Intents.DatabaseLocked);
RegisterReceiver(_intentReceiver, filter);
}
private void OnUnlock(int quickUnlockLength, EditText pwd)
{
KcpPassword kcpPassword = (KcpPassword) App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof (KcpPassword));
@ -150,9 +152,7 @@ namespace keepass2android
protected override void OnResume()
{
base.OnResume();
_design.ReapplyTheme();
CheckIfUnloaded();
EditText pwd = (EditText) FindViewById(Resource.Id.QuickUnlock_password);

View File

@ -1,9 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fitsSystemWindows="true">
<keepass2android.MeasuringRelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/relative_layout">
<LinearLayout
android:id="@+id/top"
android:layout_width="match_parent"
@ -150,4 +156,5 @@ android:paddingRight="16dp"
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
</keepass2android.MeasuringRelativeLayout>
</LinearLayout>

View File

@ -1,414 +1,378 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
<keepass2android.FixedDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true">
<!-- activity view -->
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal" />
<RelativeLayout
android:id="@+id/bottom_bar"
android:layout_width="match_parent"
<!-- activity view -->
<keepass2android.MeasuringRelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/relative_layout"
android:background="#ffffffff">
<LinearLayout
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal" />
<RelativeLayout
android:id="@+id/bottom_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:baselineAligned="false">
<Button
android:id="@+id/change_db"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:baselineAligned="false">
<Button
android:id="@+id/change_db"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="@string/menu_change_db"
style="@style/BottomBarButton" />
<Button
android:id="@+id/pass_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="@string/unlock_database_button"
style="@style/BottomBarButton" />
</RelativeLayout>
<View
android:id="@+id/divider2"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_above="@id/bottom_bar"
android:background="#b8b8b8" />
<android.support.design.widget.CoordinatorLayout
android:layout_alignParentLeft="true"
android:text="@string/menu_change_db"
style="@style/BottomBarButton" />
<Button
android:id="@+id/pass_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="@string/unlock_database_button"
style="@style/BottomBarButton" />
</RelativeLayout>
<View
android:id="@+id/divider2"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_above="@id/bottom_bar"
android:background="#b8b8b8" />
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/divider2"
android:layout_below="@id/top"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="@dimen/detail_backdrop_height"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorAccent"
app:expandedTitleMarginStart="16dp"
app:expandedTitleMarginEnd="24dp"
app:expandedTitleMarginBottom="20sp">
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:fitsSystemWindows="true"
android:layout_height="fill_parent">
<ImageView
android:id="@+id/backdrop"
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="@dimen/detail_backdrop_height"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorAccent"
app:expandedTitleMarginStart="16dp"
app:expandedTitleMarginEnd="24dp"
app:expandedTitleMarginBottom="20sp">
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:fitsSystemWindows="true"
android:layout_height="fill_parent">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
android:src="@drawable/toolbar_bg"
app:layout_collapseMode="parallax" />
<TextView
android:id="@+id/filename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="4sp"
android:layout_marginLeft="16dp"
android:textSize="10sp"
android:text="/storage/emulated/0/keepass/keepass/database.kdbx" />
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/mytoolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
android:src="@drawable/toolbar_bg"
app:layout_collapseMode="parallax" />
<TextView
android:id="@+id/filename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="4sp"
android:layout_marginLeft="16dp"
android:textSize="10sp"
android:text="/storage/emulated/0/keepass/keepass/database.kdbx" />
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/mytoolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
<TextView
android:id="@+id/password_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:text="@string/master_key_type" />
<Spinner
android:id="@+id/password_mode_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="-8dp"
android:entries="@array/password_modes" />
<View
android:id="@+id/line_below_spinner"
android:background="#e0e0e0ff"
android:layout_width="fill_parent"
android:layout_height="1dip"
android:layout_marginTop="8dp"
android:layout_centerVertical="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:layout_marginTop="16dp"
android:text="@string/hint_login_pass" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:singleLine="true"
android:inputType="textPassword"
android:fontFamily="sans-serif"
android:hint="@string/hint_login_pass" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="12dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<ImageButton
android:id="@+id/toggle_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_menu_view"
android:background="?android:selectableItemBackground" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/keyfileLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:baselineAligned="false"
android:orientation="vertical">
<TextView
android:id="@+id/keyfile_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/keyfile_heading" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/filestorage_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_storage_file"
android:padding="5dp" />
<TextView
android:id="@+id/filestorage_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Local file (TODO!)"
android:textSize="16dp" />
</LinearLayout>
<TextView
android:id="@+id/label_keyfilename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[path]"
android:layout_marginLeft="16dp" />
<Button
android:id="@+id/btn_change_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="@string/button_change_location"
style="@style/TextAppearance_SubElement" />
</LinearLayout>
<LinearLayout
android:id="@+id/otpView"
android:layout_marginLeft="12dip"
android:layout_marginRight="12dip"
android:layout_marginTop="16dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/otpInitView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/init_otp"
android:text="@string/init_otp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/otps_pending"
android:text="@string/otps_pending"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="@+id/otpEntry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical">
<TextView
android:id="@+id/otp_expl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/otp_explanation" />
<EditText
android:id="@+id/otp1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="93317749"
android:singleLine="true" />
<EditText
android:id="@+id/otp2"
android:text="54719327"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<EditText
android:id="@+id/otp3"
android:text="49844651"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<EditText
android:id="@+id/otp4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<EditText
android:id="@+id/otp5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<EditText
android:id="@+id/otp6"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/otpSecretLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<EditText
android:id="@+id/pass_otpsecret"
android:layout_width="0px"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_weight="1"
android:hint="@string/otpsecret_hint" />
<Spinner
android:id="@+id/otpsecret_format_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:id="@+id/kill_app"
android:text="@string/kill_app_label"
android:layout_width="fill_parent"
android:layout_marginTop="16dp"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/enable_quickunlock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/enable_quickunlock" />
<View
android:id="@+id/spacing"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:background="#0000" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
</keepass2android.MeasuringRelativeLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
android:fitsSystemWindows="true">
<LinearLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:id="@+id/navdrawercontents"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
<TextView
android:id="@+id/password_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:text="@string/master_key_type" />
<Spinner
android:id="@+id/password_mode_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:entries="@array/password_modes"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:layout_marginTop="16dp"
android:text="@string/hint_login_pass" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:singleLine="true"
android:inputType="textPassword"
android:hint="@string/hint_login_pass" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="12dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<ImageButton
android:id="@+id/toggle_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_menu_view"
android:background="?android:selectableItemBackground" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/keyfileLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:baselineAligned="false"
android:layout_width="wrap_content"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:orientation="vertical">
<TextView
android:id="@+id/keyfile_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/keyfile_heading" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/filestorage_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_storage_file"
android:padding="5dp"
/>
<TextView
android:id="@+id/filestorage_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Local file (TODO!)"
android:textSize="16dp" >
</TextView>
</LinearLayout>
<TextView
android:id="@+id/label_keyfilename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[path]"
android:layout_marginLeft="16dp"
/>
<Button android:id="@+id/btn_change_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="@string/button_change_location"
style="@style/TextAppearance_SubElement"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/otpView"
android:layout_marginLeft="12dip"
android:layout_marginRight="12dip"
android:layout_marginTop="16dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout
android:id="@+id/otpInitView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<Button
android:id="@+id/init_otp"
android:text="@string/init_otp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/otps_pending"
android:text="@string/otps_pending"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="@+id/otpEntry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical"
>
<TextView
android:id="@+id/otp_expl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/otp_explanation" />
<EditText
android:id="@+id/otp1"
android:layout_width="fill_parent"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="192dp">
<ImageView
android:id="@+id/navheader_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/navheader_bg" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="93317749"
android:singleLine="true" />
<EditText
android:id="@+id/otp2"
android:text="54719327"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<EditText
android:id="@+id/otp3"
android:text="49844651"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<EditText
android:id="@+id/otp4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<EditText
android:id="@+id/otp5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<EditText
android:id="@+id/otp6"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/otpSecretLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<EditText
android:id="@+id/pass_otpsecret"
android:layout_width="0px"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_weight="1"
android:hint="@string/otpsecret_hint" />
<Spinner
android:id="@+id/otpsecret_format_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<Button
android:id="@+id/kill_app"
android:text="@string/kill_app_label"
android:layout_width="fill_parent"
android:layout_marginTop="16dp"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/enable_quickunlock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/enable_quickunlock" />
<View
android:id="@+id/spacing"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:background="#0000" />
android:text="@string/app_name"
android:textSize="16dp"
android:layout_margin="16dp"
android:textColor="#fff"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp" />
</RelativeLayout>
<Button
android:id="@+id/btn_nav_change_db"
android:text="@string/menu_change_db"
android:drawableLeft="@drawable/ic_nav_changedb"
style="@style/NavDrawerButton" />
<Button
android:id="@+id/btn_nav_settings"
android:drawableLeft="@drawable/ic_nav_settings"
android:text="@string/menu_app_settings"
style="@style/NavDrawerButton" />
<Button
android:id="@+id/btn_nav_donate"
android:drawableLeft="@drawable/ic_nav_donate"
android:text="@string/menu_donate"
style="@style/NavDrawerButton" />
<Button
android:id="@+id/btn_nav_about"
android:drawableLeft="@drawable/ic_nav_about"
android:text="@string/menu_about"
style="@style/NavDrawerButton" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
android:fitsSystemWindows="true">
<LinearLayout
android:id="@+id/navdrawercontents"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="192dp">
<ImageView
android:id="@+id/navheader_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/navheader_bg"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="16dp"
android:layout_margin="16dp"
android:textColor="#fff"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp"/>
</RelativeLayout>
<Button
android:id="@+id/btn_nav_change_db"
android:text="@string/menu_change_db"
android:drawableLeft="@drawable/ic_nav_changedb"
style="@style/NavDrawerButton" />
<Button
android:id="@+id/btn_nav_settings"
android:drawableLeft="@drawable/ic_nav_settings"
android:text="@string/menu_app_settings"
style="@style/NavDrawerButton" />
<Button
android:id="@+id/btn_nav_donate"
android:drawableLeft="@drawable/ic_nav_donate"
android:text="@string/menu_donate"
style="@style/NavDrawerButton" />
<Button
android:id="@+id/btn_nav_about"
android:drawableLeft="@drawable/ic_nav_about"
android:text="@string/menu_about"
style="@style/NavDrawerButton" />
</LinearLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
</android.support.design.widget.NavigationView>
</keepass2android.FixedDrawerLayout>

View File

@ -137,8 +137,8 @@
<Compile Include="icons\DrawableFactory.cs" />
<Compile Include="icons\Icons.cs" />
<Compile Include="KeeChallenge.cs" />
<Compile Include="MainActivity.cs" />
<Compile Include="MyRelativeLayout.cs" />
<Compile Include="FixedDrawerLayout.cs" />
<Compile Include="MeasuringRelativeLayout.cs" />
<Compile Include="NfcOtpActivity.cs" />
<Compile Include="pluginhost\PluginArrayAdapter.cs" />
<Compile Include="pluginhost\PluginDatabase.cs" />
@ -1278,9 +1278,4 @@
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\oktoberfest.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\Main.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
</Project>