Added detail page for tunnels and a two-pane layout for large screens

There are a lot of changes here:
- The main_content FrameLayout is now main_fragment (more logical name).
- TunnelEntry now stores a Context instead of a TunnelEntryLoader (so
  it can be instantiated inside the detail Fragment).
- The activity_navdrawer layout is now an alias to a one-pane or two-pane
  layout depending on screen size.
- Subclasses of I2PActivityBase can now override canUseTwoPanes() to enable
  and use the two-pane layout (for devices that support it).
This commit is contained in:
str4d
2013-08-22 14:52:00 +00:00
parent 32d8a7112c
commit f4f849182d
20 changed files with 377 additions and 61 deletions

View File

@ -73,6 +73,10 @@
android:label="I2PTunnel"
android:launchMode="singleTop" >
</activity>
<activity android:name=".activity.I2PTunnelDetailActivity"
android:label="I2PTunnel"
android:parentActivityName=".activity.I2PTunnelActivity" >
</activity>
<activity android:name=".activity.LogActivity"
android:label="I2P Logs"
android:parentActivityName=".activity.MainActivity" >

View File

@ -9,7 +9,7 @@
<!-- The main content view -->
<FrameLayout
android:id="@+id/main_content"
android:id="@+id/main_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal" >
<!--
This layout is a two-pane layout for the master/detail
flow within a DrawerLayout. See res/values-large/refs.xml
and res/values-sw600dp/refs.xml for layout aliases
that replace the single-pane version of the layout with
this two-pane version.
-->
<!-- The main fragment view -->
<FrameLayout
android:id="@+id/main_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<!-- The detail fragment view -->
<FrameLayout
android:id="@+id/detail_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
<!-- The navigation drawer -->
<ListView
android:id="@+id/drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- The name of the tunnel -->
<TextView android:id="@+id/tunnel_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp"
android:textSize="16sp"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dp"
android:text="Tunnel name" />
<!-- The type of tunnel -->
<TextView android:id="@+id/tunnel_type"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tunnel_name"
android:text="Tunnel type" />
<!-- Additional tunnel details -->
<TextView android:id="@+id/tunnel_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tunnel_type"
android:text="Tunnel details" />
<!-- Interface:port the tunnel listens on or points to -->
<TextView android:id="@+id/tunnel_interface_port"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/tunnel_name"
android:layout_alignParentRight="true"
android:layout_alignTop="@id/tunnel_name"
android:gravity="right"
android:text="Interface:port" />
</RelativeLayout>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="activity_navdrawer" type="layout">@layout/activity_navdrawer_twopane</item>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="activity_navdrawer" type="layout">@layout/activity_navdrawer_twopane</item>
</resources>

4
res/values/refs.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="activity_navdrawer" type="layout">@layout/activity_navdrawer_onepane</item>
</resources>

View File

@ -23,7 +23,7 @@ public class AddressbookActivity extends I2PActivityBase
AddressbookFragment f = new AddressbookFragment();
f.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(R.id.main_content, f).commit();
.add(R.id.main_fragment, f).commit();
}
}
@ -46,7 +46,7 @@ public class AddressbookActivity extends I2PActivityBase
args.putString(WebFragment.HTML_URI, "http://" + host + '/');
f.setArguments(args);
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_content, f)
.replace(R.id.main_fragment, f)
.addToBackStack(null)
.commit();
@ -65,7 +65,7 @@ public class AddressbookActivity extends I2PActivityBase
}
private void filterAddresses(String query) {
Fragment f = getSupportFragmentManager().findFragmentById(R.id.main_content);
Fragment f = getSupportFragmentManager().findFragmentById(R.id.main_fragment);
if (f instanceof AddressbookFragment) {
AddressbookFragment af = (AddressbookFragment) f;
af.filterAddresses(query);

View File

@ -19,7 +19,7 @@ public class HelpActivity extends I2PActivityBase {
HelpFragment f = new HelpFragment();
f.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(R.id.main_content, f).commit();
.add(R.id.main_fragment, f).commit();
}*/
}

View File

@ -31,10 +31,26 @@ public class I2PActivityBase extends ActionBarActivity {
private CharSequence mTitle;
private String[] mActivityTitles;
/**
* Override this in subclasses that can use two panes, such as a
* list/detail class.
* @return whether this Activity can use a two-pane layout.
*/
protected boolean canUseTwoPanes() {
return false;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navdrawer);
// If the Activity can make use of two panes (if available),
// load the layout that will enable them. Otherwise, load the
// layout that will only ever have a single pane.
if (canUseTwoPanes())
setContentView(R.layout.activity_navdrawer);
else
setContentView(R.layout.activity_navdrawer_onepane);
mTitle = mDrawerTitle = getTitle();
mActivityTitles = getResources().getStringArray(R.array.navdrawer_activity_titles);
@ -138,7 +154,7 @@ public class I2PActivityBase extends ActionBarActivity {
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.main_content, fragment)
.replace(R.id.main_fragment, fragment)
.commit();
// Highlight the selected item, update the title, and close the drawer
@ -169,7 +185,7 @@ public class I2PActivityBase extends ActionBarActivity {
@Override
public void onBackPressed() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_content);
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_fragment);
if (fragment instanceof I2PFragmentBase) {
I2PFragmentBase ifb = (I2PFragmentBase) fragment;
// If we shouldn't stay on this fragment, go back.
@ -187,7 +203,7 @@ public class I2PActivityBase extends ActionBarActivity {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.main_content, mFragment);
ft.replace(R.id.main_fragment, mFragment);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {

View File

@ -1,15 +1,26 @@
package net.i2p.android.router.activity;
import net.i2p.android.router.R;
import net.i2p.android.router.fragment.I2PTunnelFragment;
import net.i2p.android.router.loader.TunnelEntry;
import net.i2p.android.router.fragment.I2PTunnelDetailFragment;
import net.i2p.android.router.fragment.I2PTunnelListFragment;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
public class I2PTunnelActivity extends I2PActivityBase
implements I2PTunnelFragment.OnTunnelSelectedListener {
implements I2PTunnelListFragment.OnTunnelSelectedListener {
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
@Override
protected boolean canUseTwoPanes() {
return true;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -19,28 +30,55 @@ public class I2PTunnelActivity extends I2PActivityBase
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Client tunnels tab
Fragment f = new I2PTunnelFragment();
I2PTunnelListFragment cf = new I2PTunnelListFragment();
Bundle args = new Bundle();
args.putBoolean(I2PTunnelFragment.SHOW_CLIENT_TUNNELS, true);
f.setArguments(args);
args.putBoolean(I2PTunnelListFragment.SHOW_CLIENT_TUNNELS, true);
cf.setArguments(args);
Tab tab = actionBar.newTab()
.setText(R.string.label_i2ptunnel_client)
.setTabListener(new TabListener(f));
.setTabListener(new TabListener(cf));
actionBar.addTab(tab);
// Server tunnels tab
f = new I2PTunnelFragment();
I2PTunnelListFragment sf = new I2PTunnelListFragment();
args = new Bundle();
args.putBoolean(I2PTunnelFragment.SHOW_CLIENT_TUNNELS, false);
f.setArguments(args);
args.putBoolean(I2PTunnelListFragment.SHOW_CLIENT_TUNNELS, false);
sf.setArguments(args);
tab = actionBar.newTab()
.setText(R.string.label_i2ptunnel_server)
.setTabListener(new TabListener(f));
.setTabListener(new TabListener(sf));
actionBar.addTab(tab);
if (findViewById(R.id.detail_fragment) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
cf.setActivateOnItemClick(true);
sf.setActivateOnItemClick(true);
}
}
// I2PTunnelFragment.OnTunnelSelectedListener
// I2PTunnelListFragment.OnTunnelSelectedListener
public void onTunnelSelected(TunnelEntry tunnel) {
public void onTunnelSelected(int tunnelId) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
I2PTunnelDetailFragment detailFrag = I2PTunnelDetailFragment.newInstance(tunnelId);
getSupportFragmentManager().beginTransaction()
.replace(R.id.detail_fragment, detailFrag).commit();
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, I2PTunnelDetailActivity.class);
detailIntent.putExtra(I2PTunnelDetailFragment.TUNNEL_ID, tunnelId);
startActivity(detailIntent);
}
}
}

View File

@ -0,0 +1,20 @@
package net.i2p.android.router.activity;
import net.i2p.android.router.R;
import net.i2p.android.router.fragment.I2PTunnelDetailFragment;
import android.os.Bundle;
public class I2PTunnelDetailActivity extends I2PActivityBase {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDrawerToggle.setDrawerIndicatorEnabled(false);
if (savedInstanceState == null) {
int tunnelId = getIntent().getIntExtra(I2PTunnelDetailFragment.TUNNEL_ID, 0);
I2PTunnelDetailFragment detailFrag = I2PTunnelDetailFragment.newInstance(tunnelId);
getSupportFragmentManager().beginTransaction()
.add(R.id.main_fragment, detailFrag).commit();
}
}
}

View File

@ -14,7 +14,7 @@ public class LicenseActivity extends I2PActivityBase {
LicenseFragment f = new LicenseFragment();
f.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(R.id.main_content, f).commit();
.add(R.id.main_fragment, f).commit();
}
}
}

View File

@ -17,7 +17,7 @@ public class MainActivity extends I2PActivityBase
MainFragment mainFragment = new MainFragment();
mainFragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(R.id.main_content, mainFragment).commit();
.add(R.id.main_fragment, mainFragment).commit();
}
}

View File

@ -0,0 +1,71 @@
package net.i2p.android.router.fragment;
import net.i2p.android.router.R;
import net.i2p.android.router.loader.TunnelEntry;
import net.i2p.i2ptunnel.TunnelControllerGroup;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class I2PTunnelDetailFragment extends Fragment {
public static final String TUNNEL_ID = "tunnel_id";
private TunnelEntry mTunnel;
public static I2PTunnelDetailFragment newInstance(int tunnelId) {
I2PTunnelDetailFragment f = new I2PTunnelDetailFragment();
Bundle args = new Bundle();
args.putInt(TUNNEL_ID, tunnelId);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TunnelControllerGroup tcg;
String error;
try {
tcg = TunnelControllerGroup.getInstance();
error = tcg == null ? getResources().getString(R.string.i2ptunnel_not_initialized) : null;
} catch (IllegalArgumentException iae) {
tcg = null;
error = iae.toString();
}
if (tcg == null) {
// Show error
} else if (getArguments().containsKey(TUNNEL_ID)) {
int tunnelId = getArguments().getInt(TUNNEL_ID);
mTunnel = new TunnelEntry(getActivity(),
tcg.getControllers().get(tunnelId),
tunnelId);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_i2ptunnel_detail, container, false);
if (mTunnel != null) {
TextView name = (TextView) v.findViewById(R.id.tunnel_name);
name.setText(mTunnel.getName());
TextView type = (TextView) v.findViewById(R.id.tunnel_type);
type.setText(mTunnel.getTypeName());
TextView ifacePort = (TextView) v.findViewById(R.id.tunnel_interface_port);
ifacePort.setText(mTunnel.getIfacePort());
TextView details = (TextView) v.findViewById(R.id.tunnel_details);
details.setText(mTunnel.getDetails());
}
return v;
}
}

View File

@ -18,21 +18,31 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
public class I2PTunnelFragment extends ListFragment
public class I2PTunnelListFragment extends ListFragment
implements LoaderManager.LoaderCallbacks<List<TunnelEntry>> {
public static final String SHOW_CLIENT_TUNNELS = "show_client_tunnels";
private static final int CLIENT_LOADER_ID = 1;
private static final int SERVER_LOADER_ID = 2;
/**
* The serialization (saved instance state) Bundle key representing the
* activated item position. Only used on tablets.
*/
private static final String STATE_ACTIVATED_POSITION = "activated_position";
OnTunnelSelectedListener mCallback;
private TunnelControllerGroup mGroup;
private TunnelEntryAdapter mAdapter;
private boolean mClientTunnels;
/**
* The current activated item position. Only used on tablets.
*/
private int mActivatedPosition = ListView.INVALID_POSITION;
private boolean mActivateOnItemClick = false;
// Container Activity must implement this interface
public interface OnTunnelSelectedListener {
public void onTunnelSelected(TunnelEntry host);
public void onTunnelSelected(int tunnelId);
}
@Override
@ -56,6 +66,24 @@ public class I2PTunnelFragment extends ListFragment
setHasOptionsMenu(true);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Restore the previously serialized activated item position.
if (savedInstanceState != null
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState
.getInt(STATE_ACTIVATED_POSITION));
}
// When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched.
getListView().setChoiceMode(
mActivateOnItemClick ? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@ -89,7 +117,17 @@ public class I2PTunnelFragment extends ListFragment
@Override
public void onListItemClick(ListView parent, View view, int pos, long id) {
mCallback.onTunnelSelected(mAdapter.getItem(pos));
super.onListItemClick(parent, view, pos, id);
mCallback.onTunnelSelected(mAdapter.getItem(pos).getId());
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
@Override
@ -108,6 +146,24 @@ public class I2PTunnelFragment extends ListFragment
}
}
/**
* Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched.
*/
public void setActivateOnItemClick(boolean activateOnItemClick) {
mActivateOnItemClick = activateOnItemClick;
}
private void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
getListView().setItemChecked(mActivatedPosition, false);
} else {
getListView().setItemChecked(position, true);
}
mActivatedPosition = position;
}
// LoaderManager.LoaderCallbacks<List<TunnelEntry>>
public Loader<List<TunnelEntry>> onCreateLoader(int id, Bundle args) {

View File

@ -61,7 +61,7 @@ public class MainFragment extends I2PFragmentBase {
public void onClick(View view) {
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main_content, new NewsFragment())
.replace(R.id.main_fragment, new NewsFragment())
.addToBackStack(null)
.commit();
}
@ -78,7 +78,7 @@ public class MainFragment extends I2PFragmentBase {
f.setArguments(args);
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main_content, f)
.replace(R.id.main_fragment, f)
.addToBackStack(null)
.commit();
}
@ -95,7 +95,7 @@ public class MainFragment extends I2PFragmentBase {
f.setArguments(args);
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main_content, f)
.replace(R.id.main_fragment, f)
.addToBackStack(null)
.commit();
}
@ -111,7 +111,7 @@ public class MainFragment extends I2PFragmentBase {
f.setArguments(args);
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main_content, f)
.replace(R.id.main_fragment, f)
.addToBackStack(null)
.commit();
}
@ -123,7 +123,7 @@ public class MainFragment extends I2PFragmentBase {
public void onClick(View view) {
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main_content, new PeersFragment())
.replace(R.id.main_fragment, new PeersFragment())
.addToBackStack(null)
.commit();
}

View File

@ -52,7 +52,7 @@ public class VersionDialog extends DialogFragment {
public void onClick(DialogInterface dialog, int id) {
I2PFragmentBase fb = (I2PFragmentBase) getActivity()
.getSupportFragmentManager()
.findFragmentById(R.id.main_content);
.findFragmentById(R.id.main_fragment);
fb.setPref(MainFragment.PREF_INSTALLED_VERSION, currentVersion);
dialog.cancel();
mListener.onFirstRun();
@ -62,7 +62,7 @@ public class VersionDialog extends DialogFragment {
public void onClick(DialogInterface dialog, int id) {
I2PFragmentBase fb = (I2PFragmentBase) getActivity()
.getSupportFragmentManager()
.findFragmentById(R.id.main_content);
.findFragmentById(R.id.main_fragment);
fb.setPref(MainFragment.PREF_INSTALLED_VERSION, currentVersion);
dialog.cancel();
TextResourceDialog f = new TextResourceDialog();
@ -71,7 +71,7 @@ public class VersionDialog extends DialogFragment {
f.setArguments(args);
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main_content, f)
.replace(R.id.main_fragment, f)
.addToBackStack(null)
.commit();
}
@ -80,7 +80,7 @@ public class VersionDialog extends DialogFragment {
public void onClick(DialogInterface dialog, int id) {
I2PFragmentBase fb = (I2PFragmentBase) getActivity()
.getSupportFragmentManager()
.findFragmentById(R.id.main_content);
.findFragmentById(R.id.main_fragment);
fb.setPref(MainFragment.PREF_INSTALLED_VERSION, currentVersion);
dialog.cancel();
Intent intent = new Intent(getActivity(), LicenseActivity.class);
@ -98,7 +98,7 @@ public class VersionDialog extends DialogFragment {
public void onClick(DialogInterface dialog, int id) {
I2PFragmentBase fb = (I2PFragmentBase) getActivity()
.getSupportFragmentManager()
.findFragmentById(R.id.main_content);
.findFragmentById(R.id.main_fragment);
fb.setPref(MainFragment.PREF_INSTALLED_VERSION, currentVersion);
try {
dialog.dismiss();
@ -110,7 +110,7 @@ public class VersionDialog extends DialogFragment {
public void onClick(DialogInterface dialog, int id) {
I2PFragmentBase fb = (I2PFragmentBase) getActivity()
.getSupportFragmentManager()
.findFragmentById(R.id.main_content);
.findFragmentById(R.id.main_fragment);
fb.setPref(MainFragment.PREF_INSTALLED_VERSION, currentVersion);
try {
dialog.dismiss();
@ -122,7 +122,7 @@ public class VersionDialog extends DialogFragment {
f.setArguments(args);
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main_content, f)
.replace(R.id.main_fragment, f)
.addToBackStack(null)
.commit();
}

View File

@ -1,16 +1,23 @@
package net.i2p.android.router.loader;
import android.content.Context;
import android.graphics.drawable.Drawable;
import net.i2p.android.router.R;
import net.i2p.i2ptunnel.TunnelController;
public class TunnelEntry {
private final TunnelEntryLoader mLoader;
private final Context mContext;
private final TunnelController mController;
private final int mId;
public TunnelEntry(TunnelEntryLoader loader, TunnelController controller) {
mLoader = loader;
public TunnelEntry(Context context, TunnelController controller, int id) {
mContext = context;
mController = controller;
mId = id;
}
public int getId() {
return mId;
}
public TunnelController getController() {
@ -41,40 +48,40 @@ public class TunnelEntry {
public String getTypeName() {
if ("client".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_client);
else if ("httpclient".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_httpclient);
else if ("ircclient".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_ircclient);
else if ("server".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_server);
else if ("httpserver".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_httpserver);
else if ("sockstunnel".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_sockstunnel);
else if ("socksirctunnel".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_socksirctunnel);
else if ("connectclient".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_connectclient);
else if ("ircserver".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_ircserver);
else if ("streamrclient".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_streamrclient);
else if ("streamrserver".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_streamrserver);
else if ("httpbidirserver".equals(mController.getType()))
return mLoader.getContext().getResources()
return mContext.getResources()
.getString(R.string.i2ptunnel_type_httpbidirserver);
else
return mController.getType();
@ -118,16 +125,16 @@ public class TunnelEntry {
public Drawable getStatusIcon() {
if (mController.getIsRunning()) {
if (isClient() && mController.getIsStandby())
return mLoader.getContext().getResources()
return mContext.getResources()
.getDrawable(R.drawable.local_inprogress);
else
return mLoader.getContext().getResources()
return mContext.getResources()
.getDrawable(R.drawable.local_up);
} else if (mController.getIsStarting())
return mLoader.getContext().getResources()
return mContext.getResources()
.getDrawable(R.drawable.local_inprogress);
else
return mLoader.getContext().getResources()
return mContext.getResources()
.getDrawable(R.drawable.local_down);
}
}

View File

@ -27,8 +27,9 @@ public class TunnelEntryLoader extends AsyncTaskLoader<List<TunnelEntry>> {
@Override
public List<TunnelEntry> loadInBackground() {
List<TunnelEntry> ret = new ArrayList<TunnelEntry>();
for (TunnelController controller : mGroup.getControllers()) {
TunnelEntry tunnel = new TunnelEntry(this, controller);
List<TunnelController> controllers = mGroup.getControllers();
for (int i = 0; i < controllers.size(); i++) {
TunnelEntry tunnel = new TunnelEntry(getContext(), controllers.get(i), i);
if ( (mClientTunnels && tunnel.isClient()) ||
(!mClientTunnels && !tunnel.isClient()) )
ret.add(tunnel);