New UI for AppRTC Android Demo that is easier to use and better follows

Android design guidelines.

BUG=
R=magjed@webrtc.org

Review URL: https://codereview.webrtc.org/1970783002 .

Cr-Commit-Position: refs/heads/master@{#12758}
This commit is contained in:
Sami Kalliomäki
2016-05-16 16:21:28 +02:00
parent ff66d6b942
commit 57f95dcf9d
13 changed files with 190 additions and 132 deletions

View File

@ -22,7 +22,9 @@
android:allowBackup="false"> android:allowBackup="false">
<activity android:name="ConnectActivity" <activity android:name="ConnectActivity"
android:label="@string/app_name"> android:label="@string/app_name"
android:theme="@style/Theme.AppCompat"
android:windowSoftInputMode="adjustPan">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

View File

@ -1,72 +1,82 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="16dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:weightSum="1" android:weightSum="1"
android:layout_margin="8dp"
android:layout_centerHorizontal="true"> android:layout_centerHorizontal="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageButton
android:id="@+id/add_room_button"
android:background="@android:drawable/ic_menu_add"
android:contentDescription="@string/add_room_description"
android:layout_marginEnd="20dp"
android:layout_width="48dp"
android:layout_height="48dp"/>
<ImageButton
android:id="@+id/remove_room_button"
android:background="@android:drawable/ic_delete"
android:contentDescription="@string/remove_room_description"
android:layout_marginEnd="20dp"
android:layout_width="48dp"
android:layout_height="48dp"/>
<ImageButton
android:id="@+id/connect_button"
android:background="@android:drawable/sym_action_call"
android:contentDescription="@string/connect_description"
android:layout_marginEnd="20dp"
android:layout_width="48dp"
android:layout_height="48dp"/>
<ImageButton
android:id="@+id/connect_loopback_button"
android:background="@drawable/ic_loopback_call"
android:contentDescription="@string/connect_loopback_description"
android:layout_width="48dp"
android:layout_height="48dp"/>
</LinearLayout>
<TextView <TextView
android:id="@+id/room_edittext_description" android:id="@+id/room_edittext_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="@string/room_description"/>
<EditText
android:id="@+id/room_edittext"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/room_description"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginBottom="8dp">
<EditText
android:id="@+id/room_edittext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true" android:singleLine="true"
android:imeOptions="actionDone"/> android:imeOptions="actionDone"
android:inputType="text"/>
<ImageButton
android:id="@+id/connect_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@string/connect_description"
android:background="@android:drawable/sym_action_call" />
</LinearLayout>
<TextView <TextView
android:id="@+id/room_listview_description" android:id="@+id/room_listview_description"
android:layout_width="fill_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="48dp"
android:layout_marginTop="5dp" android:layout_marginTop="8dp"
android:lines="1" android:lines="1"
android:maxLines="1" android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/room_names"/> android:text="@string/favorites"
android:gravity="center_vertical"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ListView <ListView
android:id="@+id/room_listview" android:id="@+id/room_listview"
android:layout_width="fill_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:listSelector="@android:color/darker_gray"
android:drawSelectorOnTop="false" /> android:drawSelectorOnTop="false" />
<TextView
android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/no_favorites" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/add_favorite_button"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_margin="8dp"
android:layout_gravity="bottom|end"
android:src="@drawable/ic_add_white_24dp"
android:contentDescription="@string/add_favorite_description"
app:backgroundTint="@android:color/holo_green_dark"
app:elevation="8dp"/>
</FrameLayout>
</LinearLayout> </LinearLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/favorite_edittext"
android:layout_gravity="center_horizontal"
android:inputType="text"/>
</LinearLayout>

View File

@ -1,8 +1,14 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_loopback"
android:icon="@drawable/ic_loopback_call"
app:showAsAction="always"
android:title="@string/action_loopback"/>
<item <item
android:id="@+id/action_settings" android:id="@+id/action_settings"
android:orderInCategory="100" android:orderInCategory="100"
android:icon="@android:drawable/ic_menu_preferences" android:icon="@android:drawable/ic_menu_preferences"
android:showAsAction="ifRoom" app:showAsAction="ifRoom"
android:title="@string/action_settings"/> android:title="@string/action_settings"/>
</menu> </menu>

View File

@ -36,4 +36,8 @@
<item>ISAC</item> <item>ISAC</item>
</string-array> </string-array>
<string-array name="roomListContextMenu">
<item>Remove favorite</item>
</string-array>
</resources> </resources>

View File

@ -3,12 +3,13 @@
<string name="app_name" translatable="no">AppRTC</string> <string name="app_name" translatable="no">AppRTC</string>
<string name="settings_name" translatable="no">AppRTC Settings</string> <string name="settings_name" translatable="no">AppRTC Settings</string>
<string name="disconnect_call">Disconnect Call</string> <string name="disconnect_call">Disconnect Call</string>
<string name="room_names">Room names:</string>
<string name="room_description"> <string name="room_description">
Please enter a room name. Room names are shared with everyone, so think Please enter a room name. Room names are shared with everyone, so think
of something unique and send it to a friend. of something unique and send it to a friend.
</string> </string>
<string name="connect_text">Connect</string> <string name="favorites">Favorites</string>
<string name="no_favorites">No favorites</string>
<string name="add_favorite_title">Add favorite</string>
<string name="invalid_url_title">Invalid URL</string> <string name="invalid_url_title">Invalid URL</string>
<string name="invalid_url_text">The URL or room name you entered resulted in an invalid URL: %1$s <string name="invalid_url_text">The URL or room name you entered resulted in an invalid URL: %1$s
</string> </string>
@ -16,14 +17,15 @@
<string name="connecting_to">Connecting to: %1$s</string> <string name="connecting_to">Connecting to: %1$s</string>
<string name="missing_url">FATAL ERROR: Missing URL to connect to.</string> <string name="missing_url">FATAL ERROR: Missing URL to connect to.</string>
<string name="ok">OK</string> <string name="ok">OK</string>
<string name="add">Add</string>
<string name="cancel">Cancel</string>
<string name="switch_camera">Switch front/back camera</string> <string name="switch_camera">Switch front/back camera</string>
<string name="toggle_debug">Toggle debug view</string> <string name="toggle_debug">Toggle debug view</string>
<string name="toggle_mic">Toggle microphone on/off</string> <string name="toggle_mic">Toggle microphone on/off</string>
<string name="action_settings">Settings</string> <string name="action_settings">Settings</string>
<string name="add_room_description">Add new room to the list</string> <string name="action_loopback">Loopback connection</string>
<string name="remove_room_description">Remove room from the list</string>
<string name="connect_description">Connect to the room</string> <string name="connect_description">Connect to the room</string>
<string name="connect_loopback_description">Loopback connection</string> <string name="add_favorite_description">Add favorite</string>
<!-- Settings strings. --> <!-- Settings strings. -->
<string name="pref_room_key">room_preference</string> <string name="pref_room_key">room_preference</string>

View File

@ -10,16 +10,19 @@
package org.appspot.apprtc; package org.appspot.apprtc;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -42,15 +45,14 @@ import java.util.Random;
/** /**
* Handles the initial setup where the user selects which room to join. * Handles the initial setup where the user selects which room to join.
*/ */
public class ConnectActivity extends Activity { public class ConnectActivity extends AppCompatActivity {
private static final String TAG = "ConnectActivity"; private static final String TAG = "ConnectActivity";
private static final int CONNECTION_REQUEST = 1; private static final int CONNECTION_REQUEST = 1;
private static final int REMOVE_FAVORITE_INDEX = 0;
private static boolean commandLineRun = false; private static boolean commandLineRun = false;
private ImageButton addRoomButton;
private ImageButton removeRoomButton;
private ImageButton connectButton; private ImageButton connectButton;
private ImageButton connectLoopbackButton; private FloatingActionButton addFavoriteButton;
private EditText roomEditText; private EditText roomEditText;
private ListView roomListView; private ListView roomListView;
private SharedPreferences sharedPref; private SharedPreferences sharedPref;
@ -114,7 +116,7 @@ public class ConnectActivity extends Activity {
public boolean onEditorAction( public boolean onEditorAction(
TextView textView, int i, KeyEvent keyEvent) { TextView textView, int i, KeyEvent keyEvent) {
if (i == EditorInfo.IME_ACTION_DONE) { if (i == EditorInfo.IME_ACTION_DONE) {
addRoomButton.performClick(); addFavoriteButton.performClick();
return true; return true;
} }
return false; return false;
@ -123,32 +125,27 @@ public class ConnectActivity extends Activity {
roomEditText.requestFocus(); roomEditText.requestFocus();
roomListView = (ListView) findViewById(R.id.room_listview); roomListView = (ListView) findViewById(R.id.room_listview);
roomListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); roomListView.setEmptyView(findViewById(android.R.id.empty));
roomListView.setOnItemClickListener(roomListClickListener);
addRoomButton = (ImageButton) findViewById(R.id.add_room_button); registerForContextMenu(roomListView);
addRoomButton.setOnClickListener(addRoomListener);
removeRoomButton = (ImageButton) findViewById(R.id.remove_room_button);
removeRoomButton.setOnClickListener(removeRoomListener);
connectButton = (ImageButton) findViewById(R.id.connect_button); connectButton = (ImageButton) findViewById(R.id.connect_button);
connectButton.setOnClickListener(connectListener); connectButton.setOnClickListener(connectListener);
connectLoopbackButton =
(ImageButton) findViewById(R.id.connect_loopback_button);
connectLoopbackButton.setOnClickListener(connectListener);
// If an implicit VIEW intent is launching the app, go directly to that URL. // If an implicit VIEW intent is launching the app, go directly to that URL.
final Intent intent = getIntent(); final Intent intent = getIntent();
if ("android.intent.action.VIEW".equals(intent.getAction()) if ("android.intent.action.VIEW".equals(intent.getAction())
&& !commandLineRun) { && !commandLineRun) {
commandLineRun = true;
boolean loopback = intent.getBooleanExtra( boolean loopback = intent.getBooleanExtra(
CallActivity.EXTRA_LOOPBACK, false); CallActivity.EXTRA_LOOPBACK, false);
int runTimeMs = intent.getIntExtra( int runTimeMs = intent.getIntExtra(
CallActivity.EXTRA_RUNTIME, 0); CallActivity.EXTRA_RUNTIME, 0);
String room = sharedPref.getString(keyprefRoom, ""); String room = sharedPref.getString(keyprefRoom, "");
roomEditText.setText(room); connectToRoom(room, true, loopback, runTimeMs);
connectToRoom(loopback, runTimeMs);
return; return;
} }
addFavoriteButton = (FloatingActionButton) findViewById(R.id.add_favorite_button);
addFavoriteButton.setOnClickListener(addFavoriteListener);
} }
@Override @Override
@ -157,6 +154,33 @@ public class ConnectActivity extends Activity {
return true; return true;
} }
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
if (v.getId() == R.id.room_listview) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
menu.setHeaderTitle(roomList.get(info.position));
String[] menuItems = getResources().getStringArray(R.array.roomListContextMenu);
for (int i = 0; i < menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
} else {
super.onCreateContextMenu(menu, v, menuInfo);
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
if (item.getItemId() == REMOVE_FAVORITE_INDEX) {
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
roomList.remove(info.position);
adapter.notifyDataSetChanged();
return true;
}
return super.onContextItemSelected(item);
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items. // Handle presses on the action bar items.
@ -164,6 +188,9 @@ public class ConnectActivity extends Activity {
Intent intent = new Intent(this, SettingsActivity.class); Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent); startActivity(intent);
return true; return true;
} else if (item.getItemId() == R.id.action_loopback) {
connectToRoom(null, false, true, 0);
return true;
} else { } else {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -217,28 +244,13 @@ public class ConnectActivity extends Activity {
} }
} }
private final OnClickListener connectListener = new OnClickListener() { private void connectToRoom(
@Override String roomId, boolean commandLineRun, boolean loopback, int runTimeMs) {
public void onClick(View view) { this.commandLineRun = commandLineRun;
boolean loopback = false;
if (view.getId() == R.id.connect_loopback_button) {
loopback = true;
}
commandLineRun = false;
connectToRoom(loopback, 0);
}
};
private void connectToRoom(boolean loopback, int runTimeMs) { // roomId is random for loopback.
// Get room name (random for loopback).
String roomId;
if (loopback) { if (loopback) {
roomId = Integer.toString((new Random()).nextInt(100000000)); roomId = Integer.toString((new Random()).nextInt(100000000));
} else {
roomId = getSelectedItem();
if (roomId == null) {
roomId = roomEditText.getText().toString();
}
} }
String roomUrl = sharedPref.getString( String roomUrl = sharedPref.getString(
@ -390,41 +402,46 @@ public class ConnectActivity extends Activity {
return false; return false;
} }
private final OnClickListener addRoomListener = new OnClickListener() { private final AdapterView.OnItemClickListener
roomListClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String roomId = ((TextView) view).getText().toString();
connectToRoom(roomId, false, false, 0);
}
};
private final OnClickListener addFavoriteListener = new OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
String newRoom = roomEditText.getText().toString(); AlertDialog.Builder builder = new AlertDialog.Builder(ConnectActivity.this);
final View dialogView = LayoutInflater.from(ConnectActivity.this)
.inflate(R.layout.dialog_add_favorite, null);
final EditText favoriteEditText = (EditText) dialogView.findViewById(R.id.favorite_edittext);
favoriteEditText.append(roomEditText.getText());
builder.setTitle(R.string.add_favorite_title)
.setPositiveButton(R.string.add, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
String newRoom = favoriteEditText.getText().toString();
if (newRoom.length() > 0 && !roomList.contains(newRoom)) { if (newRoom.length() > 0 && !roomList.contains(newRoom)) {
adapter.add(newRoom); adapter.add(newRoom);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
} }
})
.setView(dialogView)
.setNegativeButton(R.string.cancel, null);
builder.show();
}
}; };
private final OnClickListener removeRoomListener = new OnClickListener() { private final OnClickListener connectListener = new OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
String selectedRoom = getSelectedItem(); connectToRoom(roomEditText.getText().toString(), false, false, 0);
if (selectedRoom != null) {
adapter.remove(selectedRoom);
adapter.notifyDataSetChanged();
}
} }
}; };
private String getSelectedItem() {
int position = AdapterView.INVALID_POSITION;
if (roomListView.getCheckedItemCount() > 0 && adapter.getCount() > 0) {
position = roomListView.getCheckedItemPosition();
if (position >= adapter.getCount()) {
position = AdapterView.INVALID_POSITION;
}
}
if (position != AdapterView.INVALID_POSITION) {
return adapter.getItem(position);
} else {
return null;
}
}
} }

View File

@ -408,6 +408,7 @@
'type': 'none', 'type': 'none',
'dependencies': [ 'dependencies': [
'api/api.gyp:libjingle_peerconnection_java', 'api/api.gyp:libjingle_peerconnection_java',
'<(DEPTH)/third_party/android_tools/android_tools.gyp:android_support_design_javalib'
], ],
'variables': { 'variables': {
'apk_name': 'AppRTCDemo', 'apk_name': 'AppRTCDemo',
@ -418,9 +419,11 @@
'R_package_relpath': 'org/appspot/apprtc', 'R_package_relpath': 'org/appspot/apprtc',
'input_jars_paths': [ 'input_jars_paths': [
'examples/androidapp/third_party/autobanh/autobanh.jar', 'examples/androidapp/third_party/autobanh/autobanh.jar',
'<(DEPTH)/third_party/android_tools/sdk/extras/android/support/v4/android-support-v4.jar',
], ],
'library_dexed_jars_paths': [ 'library_dexed_jars_paths': [
'examples/androidapp/third_party/autobanh/autobanh.jar', 'examples/androidapp/third_party/autobanh/autobanh.jar',
'<(DEPTH)/third_party/android_tools/sdk/extras/android/support/v4/android-support-v4.jar',
], ],
'native_lib_target': 'libjingle_peerconnection_so', 'native_lib_target': 'libjingle_peerconnection_so',
'add_to_dependents_classpaths':1, 'add_to_dependents_classpaths':1,