major ui improvement to the list using SwipeListView

This commit is contained in:
zeapo
2014-08-17 01:13:46 +02:00
parent 3debc05707
commit 1858fb5e52
11 changed files with 305 additions and 238 deletions

View File

@@ -18,10 +18,16 @@ android {
} }
} }
} }
repositories {
maven { url 'http://clinker.47deg.com/nexus/content/groups/public' }
}
dependencies { dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':libraries:openpgp-api-lib') compile project(':libraries:openpgp-api-lib')
compile 'org.eclipse.jgit:org.eclipse.jgit:3.4.+' compile 'org.eclipse.jgit:org.eclipse.jgit:3.4.+'
compile 'org.apache.commons:commons-io:1.3.2' compile 'org.apache.commons:commons-io:1.3.2'
compile ('com.fortysevendeg.swipelistview:swipelistview:1.0-SNAPSHOT@aar') {
transitive = true
}
} }

View File

@@ -1,20 +1,27 @@
package com.zeapo.pwdstore; package com.zeapo.pwdstore;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.app.Fragment; import android.app.Fragment;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.AbsListView; import android.widget.AbsListView;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ExpandableListAdapter; import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.ListAdapter; import android.widget.ListAdapter;
import android.widget.ListView; import android.widget.ListView;
import com.fortysevendeg.swipelistview.BaseSwipeListViewListener;
import com.fortysevendeg.swipelistview.SwipeListView;
import com.fortysevendeg.swipelistview.SwipeListViewListener;
import com.zeapo.pwdstore.utils.PasswordAdapter; import com.zeapo.pwdstore.utils.PasswordAdapter;
import com.zeapo.pwdstore.utils.PasswordItem; import com.zeapo.pwdstore.utils.PasswordItem;
import com.zeapo.pwdstore.utils.PasswordRepository; import com.zeapo.pwdstore.utils.PasswordRepository;
@@ -29,14 +36,14 @@ import java.util.List;
* with a GridView. * with a GridView.
* <p /> * <p />
*/ */
public class PasswordFragment extends Fragment implements ExpandableListView.OnGroupClickListener { public class PasswordFragment extends Fragment implements SwipeListViewListener {
private OnFragmentInteractionListener mListener; private OnFragmentInteractionListener mListener;
/** /**
* The fragment's ListView/GridView. * The fragment's ListView/GridView.
*/ */
private ExpandableListView mListView; private SwipeListView mListView;
/** /**
* The Adapter which will be used to populate the ListView/GridView with * The Adapter which will be used to populate the ListView/GridView with
@@ -64,11 +71,11 @@ public class PasswordFragment extends Fragment implements ExpandableListView.OnG
View view = inflater.inflate(R.layout.fragment_password, container, false); View view = inflater.inflate(R.layout.fragment_password, container, false);
// Set the adapter // Set the adapter
mListView = (ExpandableListView) view.findViewById(R.id.pass_list); mListView = (SwipeListView) view.findViewById(R.id.pass_list);
mListView.setAdapter((android.widget.ExpandableListAdapter) mAdapter); ((AdapterView<ListAdapter>) mListView).setAdapter(mAdapter);
// Set OnItemClickListener so we can be notified on item clicks // Set OnItemClickListener so we can be notified on item clicks
mListView.setOnGroupClickListener(this); // mListView.setOnItemClickListener(this);
mListView.setSwipeListViewListener(this);
mListView.setSelectionFromTop(getArguments().getInt("Position"), 0); mListView.setSelectionFromTop(getArguments().getInt("Position"), 0);
return view; return view;
@@ -98,23 +105,105 @@ public class PasswordFragment extends Fragment implements ExpandableListView.OnG
} }
@Override // @Override
public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if( ((PasswordItem) mAdapter.getGroup(i)).getType() == PasswordItem.TYPE_CATEGORY ){ PasswordItem item = mAdapter.getItem(position);
if (null != mListener) { if (item.getType() == PasswordItem.TYPE_PASSWORD) {
// Notify the active callbacks interface (the activity, if the // if (item.selected) {
// fragment is attached to one) that an item has been selected. // item.selected = false;
mListener.onFragmentInteraction(mAdapter.getItem(i)); // } else {
} // View right = view.findViewById(R.id.row_buttons);
} else { // ScaleAnimation animation = new ScaleAnimation(view.getX(), 0, view.getY(), 0, Animation.RELATIVE_TO_SELF, (float)0.5, Animation.RELATIVE_TO_SELF, (float)0.5);
if (expandableListView.isGroupExpanded(i)) { // right.setAnimation(animation);
expandableListView.collapseGroup(i); // item.selected = true;
} else { // }
expandableListView.expandGroup(i); } else if (null != mListener) {
} // Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onFragmentInteraction(mAdapter.getItem(position));
} }
return true; }
@Override
public void onOpened(int i, boolean b) {
}
@Override
public void onClosed(int i, boolean b) {
}
@Override
public void onListChanged() {
}
@Override
public void onMove(int i, float v) {
}
@Override
public void onStartOpen(int i, int i2, boolean b) {
}
@Override
public void onStartClose(int i, boolean b) {
}
@Override
public void onClickFrontView(int i) {
if (mAdapter.getItem(i).getType() == PasswordItem.TYPE_PASSWORD) {
mListView.openAnimate(i);
} else if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onFragmentInteraction(mAdapter.getItem(i));
}
}
@Override
public void onClickBackView(int i) {
mListView.closeAnimate(i);
}
@Override
public void onDismiss(int[] ints) {
}
@Override
public int onChangeSwipeMode(int i) {
return 0;
}
@Override
public void onChoiceChanged(int i, boolean b) {
}
@Override
public void onChoiceStarted() {
}
@Override
public void onChoiceEnded() {
}
@Override
public void onFirstListItem() {
}
@Override
public void onLastListItem() {
} }
public interface OnFragmentInteractionListener { public interface OnFragmentInteractionListener {
@@ -125,7 +214,7 @@ public class PasswordFragment extends Fragment implements ExpandableListView.OnG
public void updateAdapter() { public void updateAdapter() {
mAdapter.clear(); mAdapter.clear();
mAdapter.addAll(PasswordRepository.getPasswords(new File(getArguments().getString("Path")))); mAdapter.addAll(PasswordRepository.getPasswords(new File(getArguments().getString("Path"))));
mListView.setAdapter((ExpandableListAdapter) mAdapter); mListView.setAdapter((ListAdapter) mAdapter);
} }
} }

View File

@@ -249,14 +249,6 @@ public class PasswordStore extends Activity implements ToCloneOrNot.OnFragmentI
public void onFragmentInteraction(PasswordItem item) { public void onFragmentInteraction(PasswordItem item) {
if (item.getType() == PasswordItem.TYPE_CATEGORY) { if (item.getType() == PasswordItem.TYPE_CATEGORY) {
checkLocalRepository(item.getFile()); checkLocalRepository(item.getFile());
} else {
try {
} catch (Exception e) {
// TODO handle problems
e.printStackTrace();
}
} }
} }
public void decryptPassword(PasswordItem item) { public void decryptPassword(PasswordItem item) {

View File

@@ -34,6 +34,7 @@ import com.zeapo.pwdstore.utils.PasswordRepository;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.util.StringUtils; import org.eclipse.jgit.util.StringUtils;
import org.openintents.openpgp.IOpenPgpService;
import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpApi;
@@ -48,7 +49,7 @@ import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.ArrayList; import java.util.ArrayList;
public class PgpHandler extends Activity { public class PgpHandler extends Activity implements OpenPgpServiceConnection.OnBound{
private OpenPgpServiceConnection mServiceConnection; private OpenPgpServiceConnection mServiceConnection;
@@ -57,6 +58,8 @@ public class PgpHandler extends Activity {
SharedPreferences settings; SharedPreferences settings;
private Activity activity; private Activity activity;
private ProgressDialog bindingDialog;
public static final int REQUEST_CODE_SIGN = 9910; public static final int REQUEST_CODE_SIGN = 9910;
public static final int REQUEST_CODE_ENCRYPT = 9911; public static final int REQUEST_CODE_ENCRYPT = 9911;
public static final int REQUEST_CODE_SIGN_AND_ENCRYPT = 9912; public static final int REQUEST_CODE_SIGN_AND_ENCRYPT = 9912;
@@ -74,7 +77,7 @@ public class PgpHandler extends Activity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
activity = this; this.activity = this;
// some persistance // some persistance
settings = PreferenceManager.getDefaultSharedPreferences(this); settings = PreferenceManager.getDefaultSharedPreferences(this);
@@ -91,31 +94,13 @@ public class PgpHandler extends Activity {
// bind to service // bind to service
mServiceConnection = new OpenPgpServiceConnection( mServiceConnection = new OpenPgpServiceConnection(
PgpHandler.this, providerPackageName); PgpHandler.this, providerPackageName, this );
mServiceConnection.bindToService(); mServiceConnection.bindToService();
bindingDialog = new ProgressDialog(this);
Bundle extra = getIntent().getExtras(); bindingDialog.setMessage("Waiting for OpenKeychain...");
if (extra.getString("Operation").equals("DECRYPT")) { bindingDialog.setCancelable(false);
setContentView(R.layout.decrypt_layout); bindingDialog.show();
((TextView) findViewById(R.id.crypto_password_file)).setText(extra.getString("NAME"));
String cat = new File(extra.getString("FILE_PATH").replace(PasswordRepository.getWorkTree().getAbsolutePath(), ""))
.getParentFile().getName();
((TextView) findViewById(R.id.crypto_password_category)).setText(cat + "/");
} else if (extra.getString("Operation").equals("ENCRYPT")) {
setContentView(R.layout.encrypt_layout);
String cat = extra.getString("FILE_PATH");
cat = cat.replace(PasswordRepository.getWorkTree().getAbsolutePath(), "");
cat = cat + "/";
((TextView) findViewById(R.id.crypto_password_category)).setText(cat);
} else if (extra.getString("Operation").equals("GET_KEY_ID")) {
setContentView(R.layout.key_id);
if (!keyIDs.isEmpty()) {
String keys = keyIDs.split(",").length > 1 ? keyIDs : keyIDs.split(",")[0];
((TextView) findViewById(R.id.crypto_key_ids)).setText(keys);
}
}
ActionBar actionBar = getActionBar(); ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true);
@@ -176,7 +161,6 @@ public class PgpHandler extends Activity {
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
Log.e(Constants.TAG, "onError getErrorId:" + error.getErrorId()); Log.e(Constants.TAG, "onError getErrorId:" + error.getErrorId());
Log.e(Constants.TAG, "onError getMessage:" + error.getMessage()); Log.e(Constants.TAG, "onError getMessage:" + error.getMessage());
Log.e(Constants.TAG, " " + error.toString());
} }
}); });
} }
@@ -279,6 +263,8 @@ public class PgpHandler extends Activity {
@Override @Override
public void onReturn(Intent result) { public void onReturn(Intent result) {
bindingDialog.dismiss();
switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS: { case OpenPgpApi.RESULT_CODE_SUCCESS: {
showToast("SUCCESS"); showToast("SUCCESS");
@@ -366,6 +352,7 @@ public class PgpHandler extends Activity {
handleError(error); handleError(error);
break; break;
} }
} }
} }
} }
@@ -462,5 +449,32 @@ public class PgpHandler extends Activity {
} }
@Override
public void onBound(IOpenPgpService service) {
Log.i("PGP", "ISBOUND!!");
Bundle extra = getIntent().getExtras();
if (extra.getString("Operation").equals("DECRYPT")) {
setContentView(R.layout.decrypt_layout);
((TextView) findViewById(R.id.crypto_password_file)).setText(extra.getString("NAME"));
String cat = new File(extra.getString("FILE_PATH").replace(PasswordRepository.getWorkTree().getAbsolutePath(), ""))
.getParentFile().getName();
((TextView) findViewById(R.id.crypto_password_category)).setText(cat + "/");
decryptAndVerify(new Intent());
} else if (extra.getString("Operation").equals("ENCRYPT")) {
setContentView(R.layout.encrypt_layout);
String cat = extra.getString("FILE_PATH");
cat = cat.replace(PasswordRepository.getWorkTree().getAbsolutePath(), "");
cat = cat + "/";
((TextView) findViewById(R.id.crypto_password_category)).setText(cat);
} else if (extra.getString("Operation").equals("GET_KEY_ID")) {
setContentView(R.layout.key_id);
if (!keyIDs.isEmpty()) {
String keys = keyIDs.split(",").length > 1 ? keyIDs : keyIDs.split(",")[0];
((TextView) findViewById(R.id.crypto_key_ids)).setText(keys);
}
}
}
} }

View File

@@ -9,9 +9,11 @@ import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.ExpandableListAdapter; import android.widget.ExpandableListAdapter;
import android.widget.GridLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
@@ -23,13 +25,14 @@ import org.apache.commons.io.FileUtils;
import java.util.ArrayList; import java.util.ArrayList;
public class PasswordAdapter extends ArrayAdapter<PasswordItem> implements ExpandableListAdapter{ public class PasswordAdapter extends ArrayAdapter<PasswordItem>{
private final PasswordStore activity; private final PasswordStore activity;
private final ArrayList<PasswordItem> values; private final ArrayList<PasswordItem> values;
static class ViewHolder { static class ViewHolder {
public TextView name; public TextView name;
public TextView type; public TextView type;
public TextView back_name;
} }
public PasswordAdapter(PasswordStore activity, ArrayList<PasswordItem> values) { public PasswordAdapter(PasswordStore activity, ArrayList<PasswordItem> values) {
@@ -38,74 +41,47 @@ public class PasswordAdapter extends ArrayAdapter<PasswordItem> implements Exp
this.activity = activity; this.activity = activity;
} }
@Override
public void registerDataSetObserver(DataSetObserver dataSetObserver) {
}
@Override @Override
public void unregisterDataSetObserver(DataSetObserver dataSetObserver) { public View getView(int i, View convertView, ViewGroup viewGroup) {
}
@Override
public int getGroupCount() {
return values.size();
}
@Override
public int getChildrenCount(int i) {
if (values.get(i).getType() == PasswordItem.TYPE_CATEGORY)
return 0;
else
return 1;
}
@Override
public Object getGroup(int i) {
return values.get(i);
}
@Override
public Object getChild(int i, int i2) {
return null;
}
@Override
public long getGroupId(int i) {
return 0;
}
@Override
public long getChildId(int i, int i2) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int i, boolean b, View convertView, ViewGroup viewGroup) {
View rowView = convertView; View rowView = convertView;
PasswordItem pass = values.get(i); final PasswordItem pass = values.get(i);
// reuse for performance, holder pattern! // reuse for performance, holder pattern!
if (rowView == null) { if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) activity LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.password_row_layout, null); rowView = inflater.inflate(R.layout.password_row_layout, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(); ViewHolder viewHolder = new ViewHolder();
viewHolder.name = (TextView) rowView.findViewById(R.id.label); viewHolder.name = (TextView) rowView.findViewById(R.id.label);
viewHolder.back_name = (TextView) rowView.findViewById(R.id.label_back);
viewHolder.type = (TextView) rowView.findViewById(R.id.type); viewHolder.type = (TextView) rowView.findViewById(R.id.type);
rowView.setTag(viewHolder); rowView.setTag(viewHolder);
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.crypto_show_button:
activity.decryptPassword(pass);
break;
case R.id.crypto_delete_button:
activity.deletePassword(pass);
break;
}
}
};
((ImageButton) rowView.findViewById(R.id.crypto_show_button)).setOnClickListener(onClickListener);
((ImageButton) rowView.findViewById(R.id.crypto_delete_button)).setOnClickListener(onClickListener);
} }
ViewHolder holder = (ViewHolder) rowView.getTag(); ViewHolder holder = (ViewHolder) rowView.getTag();
holder.name.setText(pass.toString()); holder.name.setText(pass.toString());
holder.back_name.setText(pass.toString());
if (pass.getType() == PasswordItem.TYPE_CATEGORY) { if (pass.getType() == PasswordItem.TYPE_CATEGORY) {
holder.name.setTextColor(this.activity.getResources().getColor(android.R.color.holo_blue_dark)); holder.name.setTextColor(this.activity.getResources().getColor(android.R.color.holo_blue_dark));
@@ -115,71 +91,11 @@ public class PasswordAdapter extends ArrayAdapter<PasswordItem> implements Exp
holder.type.setText("Password: "); holder.type.setText("Password: ");
holder.name.setTextColor(this.activity.getResources().getColor(android.R.color.holo_orange_dark)); holder.name.setTextColor(this.activity.getResources().getColor(android.R.color.holo_orange_dark));
holder.name.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)); holder.name.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
holder.back_name.setTextColor(this.activity.getResources().getColor(android.R.color.white));
holder.back_name.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD_ITALIC));
} }
return rowView; return rowView;
} }
@Override
public View getChildView(int i, int i2, boolean b, View view, ViewGroup viewGroup) {
final PasswordItem pass = values.get(i);
LayoutInflater inflater = (LayoutInflater) this.activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.child_row_layout, null);
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.crypto_show_button:
activity.decryptPassword(pass);
break;
case R.id.crypto_delete_button:
activity.deletePassword(pass);
break;
}
}
};
((ImageButton) view.findViewById(R.id.crypto_show_button)).setOnClickListener(onClickListener);
((ImageButton) view.findViewById(R.id.crypto_delete_button)).setOnClickListener(onClickListener);
return view;
}
@Override
public boolean isChildSelectable(int i, int i2) {
return false;
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public void onGroupExpanded(int i) {
}
@Override
public void onGroupCollapsed(int i) {
}
@Override
public long getCombinedChildId(long l, long l2) {
return 0;
}
@Override
public long getCombinedGroupId(long l) {
return 0;
}
} }

View File

@@ -11,6 +11,7 @@ public class PasswordItem implements Comparable{
private String name; private String name;
private PasswordItem parent; private PasswordItem parent;
private File file; private File file;
public boolean selected = false;
/** Create a password item /** Create a password item
* *

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle"
android:dither="true">
<corners android:radius="2dp"/>
<solid android:color="#ccc" />
</shape>
</item>
<item android:bottom="2dp">
<shape android:shape="rectangle" android:dither="true">
<corners android:radius="2dp" />
<solid android:color="@android:color/darker_gray" />
<padding android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp" />
</shape>
</item>
</layer-list>

View File

@@ -2,7 +2,9 @@
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent" android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:id="@+id/child_row_layout"
android:layout_marginTop="@dimen/activity_vertical_margin">
<ImageButton <ImageButton
android:id="@+id/crypto_delete_button" android:id="@+id/crypto_delete_button"

View File

@@ -9,13 +9,14 @@
<LinearLayout <LinearLayout
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<GridLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/rectangle"> android:background="@drawable/rectangle"
android:orientation="vertical">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -24,10 +25,7 @@
android:text="CATEGORY HERE" android:text="CATEGORY HERE"
android:id="@+id/crypto_password_category" android:id="@+id/crypto_password_category"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp" android:layout_marginLeft="@dimen/activity_horizontal_margin"/>
android:layout_column="0"
android:layout_row="0"
android:layout_columnSpan="2"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -38,38 +36,8 @@
android:text="PASSWORD FILE NAME HERE" android:text="PASSWORD FILE NAME HERE"
android:id="@+id/crypto_password_file" android:id="@+id/crypto_password_file"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp" android:layout_marginLeft="@dimen/activity_horizontal_margin"/>
android:layout_column="0" </LinearLayout>
android:layout_columnSpan="2"
android:layout_row="1"/>
<ImageButton
android:id="@+id/crypto_delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ico_del"
android:background="@drawable/red_rectangle"
android:layout_gravity="center_vertical"
android:onClick="handleClick"
android:layout_column="3"
android:layout_row="0"
android:layout_rowSpan="2"/>
<ImageButton
android:id="@+id/crypto_show_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ico_key"
android:background="@drawable/blue_rectangle"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
android:onClick="handleClick"
android:layout_column="4"
android:layout_row="0"
android:layout_rowSpan="2"/>
</GridLayout>
<LinearLayout <LinearLayout
android:id="@+id/crypto_container" android:id="@+id/crypto_container"

View File

@@ -5,12 +5,21 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.zeapo.pwdstore.PasswordFragment"> tools:context="com.zeapo.pwdstore.PasswordFragment">
<ExpandableListView <com.fortysevendeg.swipelistview.SwipeListView
xmlns:swipe="http://schemas.android.com/apk/res-auto"
android:id="@+id/pass_list" android:id="@+id/pass_list"
android:layout_width="match_parent" android:layout_width="fill_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:dividerHeight="@dimen/activity_vertical_margin" android:dividerHeight="@dimen/activity_vertical_margin"
android:divider="@android:color/transparent" android:divider="@android:color/transparent"
android:groupIndicator="@android:drawable/screen_background_light_transparent"/> swipe:swipeFrontView="@+id/front"
swipe:swipeBackView="@+id/back"
swipe:swipeActionLeft="reveal"
swipe:swipeActionRight="reveal"
swipe:swipeMode="both"
swipe:swipeCloseAllItemsWhenMoveList="true"
swipe:swipeOpenOnLongPress="true"
swipe:swipeAnimationTime="200"
android:listSelector="#00000000"/>
</FrameLayout> </FrameLayout>

View File

@@ -1,25 +1,71 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="fill_parent"
android:layout_height="match_parent" android:layout_height="fill_parent">
android:id="@+id/pass_row_layout"
android:background="@drawable/rectangle"
android:orientation="horizontal"> <GridLayout
<TextView android:id="@+id/back"
android:id="@+id/type" android:orientation="horizontal"
android:text="TYPE" android:layout_width="match_parent"
android:layout_column="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="8dp" android:tag="back"
android:textStyle="bold" android:background="@drawable/gray_rectangle"
android:layout_gravity="center_vertical" android:layout_gravity="left|center_vertical">
/>
<TextView <TextView
android:id="@+id/label" android:id="@+id/label_back"
android:text="FILE_NAME" android:text="FILE_NAME"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:padding="8dp"/> android:padding="8dp"
</GridLayout> android:layout_column="0"/>
<ImageButton
android:id="@+id/crypto_delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ico_del"
android:background="@drawable/red_rectangle"
android:layout_gravity="center_vertical"
android:layout_column="2"/>
<ImageButton
android:id="@+id/crypto_show_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ico_key"
android:background="@drawable/blue_rectangle"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
android:layout_column="3"/>
</GridLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/front"
android:tag="front"
android:background="@android:color/white"
android:layout_gravity="left|center_vertical">
<TextView
android:id="@+id/type"
android:text="TYPE"
android:layout_column="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textStyle="bold"
android:layout_gravity="center_vertical"
/>
<TextView
android:id="@+id/label"
android:text="FILE_NAME"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp"/>
</LinearLayout>
</FrameLayout>