Move menu items to drawer (fixes #110).

This commit is contained in:
Felix Ableitner 2015-01-20 19:02:52 +01:00
parent 8d676855da
commit 5c11c426ab
27 changed files with 153 additions and 99 deletions

View File

@ -5,7 +5,6 @@ import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
@ -22,20 +21,19 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab; import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBar.TabListener; import android.support.v7.app.ActionBar.TabListener;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.fragments.DevicesFragment; import com.nutomic.syncthingandroid.fragments.DevicesFragment;
import com.nutomic.syncthingandroid.fragments.DrawerFragment;
import com.nutomic.syncthingandroid.fragments.FoldersFragment; import com.nutomic.syncthingandroid.fragments.FoldersFragment;
import com.nutomic.syncthingandroid.fragments.LocalDeviceInfoFragment;
import com.nutomic.syncthingandroid.syncthing.SyncthingService; import com.nutomic.syncthingandroid.syncthing.SyncthingService;
/** /**
* Shows {@link com.nutomic.syncthingandroid.fragments.FoldersFragment} and {@link com.nutomic.syncthingandroid.fragments.DevicesFragment} in different tabs, and * Shows {@link com.nutomic.syncthingandroid.fragments.FoldersFragment} and {@link com.nutomic.syncthingandroid.fragments.DevicesFragment} in different tabs, and
* {@link com.nutomic.syncthingandroid.fragments.LocalDeviceInfoFragment} in the navigation drawer. * {@link com.nutomic.syncthingandroid.fragments.DrawerFragment} in the navigation drawer.
*/ */
public class MainActivity extends SyncthingActivity public class MainActivity extends SyncthingActivity
implements SyncthingService.OnApiChangeListener { implements SyncthingService.OnApiChangeListener {
@ -127,7 +125,7 @@ public class MainActivity extends SyncthingActivity
private DevicesFragment mDevicesFragment; private DevicesFragment mDevicesFragment;
private LocalDeviceInfoFragment mLocalDeviceInfoFragment; private DrawerFragment mDrawerFragment;
private ViewPager mViewPager; private ViewPager mViewPager;
@ -182,18 +180,18 @@ public class MainActivity extends SyncthingActivity
savedInstanceState, FoldersFragment.class.getName()); savedInstanceState, FoldersFragment.class.getName());
mDevicesFragment = (DevicesFragment) fm.getFragment( mDevicesFragment = (DevicesFragment) fm.getFragment(
savedInstanceState, DevicesFragment.class.getName()); savedInstanceState, DevicesFragment.class.getName());
mLocalDeviceInfoFragment = (LocalDeviceInfoFragment) fm.getFragment( mDrawerFragment = (DrawerFragment) fm.getFragment(
savedInstanceState, LocalDeviceInfoFragment.class.getName()); savedInstanceState, DrawerFragment.class.getName());
mViewPager.setCurrentItem(savedInstanceState.getInt("currentTab")); mViewPager.setCurrentItem(savedInstanceState.getInt("currentTab"));
} else { } else {
mFolderFragment = new FoldersFragment(); mFolderFragment = new FoldersFragment();
mDevicesFragment = new DevicesFragment(); mDevicesFragment = new DevicesFragment();
mLocalDeviceInfoFragment = new LocalDeviceInfoFragment(); mDrawerFragment = new DrawerFragment();
} }
getSupportFragmentManager() getSupportFragmentManager()
.beginTransaction() .beginTransaction()
.replace(R.id.drawer, mLocalDeviceInfoFragment) .replace(R.id.drawer, mDrawerFragment)
.commit(); .commit();
mDrawerToggle = new Toggle(this, mDrawerLayout, R.drawable.ic_drawer); mDrawerToggle = new Toggle(this, mDrawerLayout, R.drawable.ic_drawer);
mDrawerLayout.setDrawerListener(mDrawerToggle); mDrawerLayout.setDrawerListener(mDrawerToggle);
@ -223,57 +221,16 @@ public class MainActivity extends SyncthingActivity
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
// Avoid crash if called during startup. // Avoid crash if called during startup.
if (mFolderFragment != null && mDevicesFragment != null && if (mFolderFragment != null && mDevicesFragment != null &&
mLocalDeviceInfoFragment != null) { mDrawerFragment != null) {
FragmentManager fm = getSupportFragmentManager(); FragmentManager fm = getSupportFragmentManager();
fm.putFragment(outState, FoldersFragment.class.getName(), mFolderFragment); fm.putFragment(outState, FoldersFragment.class.getName(), mFolderFragment);
fm.putFragment(outState, DevicesFragment.class.getName(), mDevicesFragment); fm.putFragment(outState, DevicesFragment.class.getName(), mDevicesFragment);
fm.putFragment(outState, LocalDeviceInfoFragment.class.getName(), fm.putFragment(outState, DrawerFragment.class.getName(),
mLocalDeviceInfoFragment); mDrawerFragment);
outState.putInt("currentTab", mViewPager.getCurrentItem()); outState.putInt("currentTab", mViewPager.getCurrentItem());
} }
} }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* Shows menu only once syncthing service is running, and shows "share" option only when
* drawer is open.
*/
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
boolean drawerOpen = mDrawerLayout.isDrawerOpen(findViewById(R.id.drawer));
menu.findItem(R.id.share_device_id).setVisible(drawerOpen);
menu.findItem(R.id.exit).setVisible(!SyncthingService.alwaysRunInBackground(this));
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mLocalDeviceInfoFragment.onOptionsItemSelected(item) ||
mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
case R.id.web_gui:
startActivity(new Intent(this, WebGuiActivity.class));
return true;
case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class)
.setAction(SettingsActivity.ACTION_APP_SETTINGS_FRAGMENT));
return true;
case R.id.exit:
stopService(new Intent(this, SyncthingService.class));
finish();
default:
return super.onOptionsItemSelected(item);
}
}
@Override @Override
protected void onPostCreate(Bundle savedInstanceState) { protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState); super.onPostCreate(savedInstanceState);
@ -286,6 +243,16 @@ public class MainActivity extends SyncthingActivity
mDrawerToggle.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig);
} }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
/** /**
* Receives drawer opened and closed events. * Receives drawer opened and closed events.
*/ */
@ -297,7 +264,7 @@ public class MainActivity extends SyncthingActivity
@Override @Override
public void onDrawerOpened(View drawerView) { public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView); super.onDrawerOpened(drawerView);
mLocalDeviceInfoFragment.onDrawerOpened(); mDrawerFragment.onDrawerOpened();
mFolderFragment.setHasOptionsMenu(false); mFolderFragment.setHasOptionsMenu(false);
mDevicesFragment.setHasOptionsMenu(false); mDevicesFragment.setHasOptionsMenu(false);
} }
@ -305,7 +272,7 @@ public class MainActivity extends SyncthingActivity
@Override @Override
public void onDrawerClosed(View view) { public void onDrawerClosed(View view) {
super.onDrawerClosed(view); super.onDrawerClosed(view);
mLocalDeviceInfoFragment.onDrawerClosed(); mDrawerFragment.onDrawerClosed();
mFolderFragment.setHasOptionsMenu(true); mFolderFragment.setHasOptionsMenu(true);
mDevicesFragment.setHasOptionsMenu(true); mDevicesFragment.setHasOptionsMenu(true);
} }

View File

@ -1,20 +1,31 @@
package com.nutomic.syncthingandroid.fragments; package com.nutomic.syncthingandroid.fragments;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.util.Pair;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.activities.MainActivity; import com.nutomic.syncthingandroid.activities.MainActivity;
import com.nutomic.syncthingandroid.activities.SettingsActivity;
import com.nutomic.syncthingandroid.activities.WebGuiActivity;
import com.nutomic.syncthingandroid.syncthing.RestApi; import com.nutomic.syncthingandroid.syncthing.RestApi;
import com.nutomic.syncthingandroid.syncthing.SyncthingService; import com.nutomic.syncthingandroid.syncthing.SyncthingService;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@ -22,8 +33,8 @@ import java.util.TimerTask;
/** /**
* Displays information about the local device. * Displays information about the local device.
*/ */
public class LocalDeviceInfoFragment extends Fragment public class DrawerFragment extends Fragment implements RestApi.OnReceiveSystemInfoListener,
implements RestApi.OnReceiveSystemInfoListener, RestApi.OnReceiveConnectionsListener { RestApi.OnReceiveConnectionsListener, ListView.OnItemClickListener {
private TextView mDeviceId; private TextView mDeviceId;
@ -41,6 +52,31 @@ public class LocalDeviceInfoFragment extends Fragment
private MainActivity mActivity; private MainActivity mActivity;
/**
* Displays menu items.
*/
private class MenuAdapter extends ArrayAdapter<Pair<Integer, Integer>> {
public MenuAdapter(Context context, List<Pair<Integer, Integer>> items) {
super(context, 0, items);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.menu_item, parent, false);
}
ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
icon.setImageResource(getItem(position).first);
TextView text = (TextView) convertView.findViewById(R.id.text);
text.setText(getItem(position).second);
return convertView;
}
}
public void onDrawerOpened() { public void onDrawerOpened() {
mTimer = new Timer(); mTimer = new Timer();
mTimer.schedule(new TimerTask() { mTimer.schedule(new TimerTask() {
@ -50,7 +86,6 @@ public class LocalDeviceInfoFragment extends Fragment
} }
}, 0, SyncthingService.GUI_UPDATE_INTERVAL); }, 0, SyncthingService.GUI_UPDATE_INTERVAL);
mActivity.supportInvalidateOptionsMenu();
} }
public void onDrawerClosed() { public void onDrawerClosed() {
@ -58,9 +93,12 @@ public class LocalDeviceInfoFragment extends Fragment
mTimer = null; mTimer = null;
} }
/**
* Populates views and menu.
*/
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.local_device_info_fragment, container, false); View view = inflater.inflate(R.layout.drawer_fragment, container, false);
mDeviceId = (TextView) view.findViewById(R.id.device_id); mDeviceId = (TextView) view.findViewById(R.id.device_id);
mCpuUsage = (TextView) view.findViewById(R.id.cpu_usage); mCpuUsage = (TextView) view.findViewById(R.id.cpu_usage);
mRamUsage = (TextView) view.findViewById(R.id.ram_usage); mRamUsage = (TextView) view.findViewById(R.id.ram_usage);
@ -68,6 +106,18 @@ public class LocalDeviceInfoFragment extends Fragment
mUpload = (TextView) view.findViewById(R.id.upload); mUpload = (TextView) view.findViewById(R.id.upload);
mAnnounceServer = (TextView) view.findViewById(R.id.announce_server); mAnnounceServer = (TextView) view.findViewById(R.id.announce_server);
ArrayList<Pair<Integer, Integer>> items = new ArrayList<>();
items.add(new Pair<>(R.drawable.ic_action_share, R.string.share_device_id));
items.add(new Pair<>(R.drawable.ic_menu_browser, R.string.web_gui_title));
items.add(new Pair<>(R.drawable.ic_action_settings, R.string.settings_title));
items.add(new Pair<>(R.drawable.ic_action_donate, R.string.donate));
if (!SyncthingService.alwaysRunInBackground(getActivity())) {
items.add(new Pair<>(R.drawable.ic_menu_close_clear_cancel, R.string.exit));
}
ListView list = (ListView) view.findViewById(android.R.id.list);
list.setAdapter(new MenuAdapter(getActivity(), items));
list.setOnItemClickListener(this);
return view; return view;
} }
@ -137,17 +187,29 @@ public class LocalDeviceInfoFragment extends Fragment
} }
/** /**
* Shares the local device ID when "share" is clicked. * Handles menu item clicks.
*/ */
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
switch (item.getItemId()) { switch (i) {
case R.id.share_device_id: case 0:
RestApi.shareDeviceId(getActivity(), mDeviceId.getText().toString()); RestApi.shareDeviceId(getActivity(), mDeviceId.getText().toString());
return true; break;
default: case 1:
return super.onOptionsItemSelected(item); startActivity(new Intent(mActivity, WebGuiActivity.class));
break;
case 2:
startActivity(new Intent(mActivity, SettingsActivity.class)
.setAction(SettingsActivity.ACTION_APP_SETTINGS_FRAGMENT));
break;
case 3:
startActivity(new Intent(
Intent.ACTION_VIEW, Uri.parse(getString(R.string.donate_url))));
break;
case 4:
mActivity.stopService(new Intent(mActivity, SyncthingService.class));
mActivity.finish();
break;
} }
} }
} }

View File

@ -44,7 +44,7 @@ public class SyncthingService extends Service {
public static final String ACTION_RESTART = "restart"; public static final String ACTION_RESTART = "restart";
/** /**
* Interval in ms at which the GUI is updated (eg {@link }LocalDeviceInfoFragment}). * Interval in ms at which the GUI is updated (eg {@link com.nutomic.syncthingandroid.fragments.DrawerFragment}).
*/ */
public static final int GUI_UPDATE_INTERVAL = 1000; public static final int GUI_UPDATE_INTERVAL = 1000;

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -12,17 +12,17 @@
<TextView <TextView
android:id="@+id/device_id_title" android:id="@+id/device_id_title"
android:text="@string/device_id"
android:textStyle="bold" android:textStyle="bold"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<TextView <TextView
android:id="@+id/device_id" android:id="@+id/device_id"
android:lines="1"
android:ellipsize="end"
android:layout_below="@id/device_id_title" android:layout_below="@id/device_id_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
@ -118,6 +118,28 @@
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</RelativeLayout> </RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="10dip" />
<View
android:layout_width="match_parent"
android:layout_height="2dip"
android:background="@android:color/darker_gray"/>
<View
android:layout_width="match_parent"
android:layout_height="10dip" />
<ListView android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" />
</LinearLayout> </LinearLayout>

View File

@ -14,7 +14,7 @@
android:id="@+id/drawer" android:id="@+id/drawer"
android:orientation="vertical" android:orientation="vertical"
android:layout_gravity="start" android:layout_gravity="start"
android:layout_width="260dip" android:layout_width="240dip"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clickable="true" android:clickable="true"
android:background="@android:color/background_light" /> android:background="@android:color/background_light" />

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:minHeight="45dip">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/share_device_id"
android:icon="@android:drawable/ic_menu_share"
android:title="@string/share_device_id"
app:showAsAction="ifRoom" />
<item
android:id="@+id/web_gui"
android:title="@string/web_gui_title" />
<item
android:id="@+id/settings"
android:title="@string/settings_title" />
<item
android:id="@+id/exit"
android:title="@string/exit" />
</menu>

View File

@ -57,7 +57,8 @@
<!-- Title for current upload rate --> <!-- Title for current upload rate -->
<string name="upload_title">Upload</string> <string name="upload_title">Upload</string>
<!-- LocalDeviceInfoFragment --> <!-- DrawerFragment -->
<!-- Same as download_title with a colon and space appended --> <!-- Same as download_title with a colon and space appended -->
<string name="download_title_colon">Download:\u0020</string> <string name="download_title_colon">Download:\u0020</string>
@ -74,6 +75,11 @@
<!-- Title for announce server status --> <!-- Title for announce server status -->
<string name="announce_server">Announce Server</string> <string name="announce_server">Announce Server</string>
<!-- Menu item to donate -->
<string name="donate">Donate</string>
<string name="donate_url" translatable="false">https://tip4commit.com/github/syncthing/syncthing-android</string>
<!-- FolderSettingsFragment --> <!-- FolderSettingsFragment -->
@ -280,8 +286,6 @@ Please report any problems you encounter via Github.</string>
<!-- SyncthingService --> <!-- SyncthingService -->
<!-- Title of the "syncthing disabled" dialog --> <!-- Title of the "syncthing disabled" dialog -->
<string name="syncthing_disabled_title">Syncthing is disabled</string> <string name="syncthing_disabled_title">Syncthing is disabled</string>