WIP: Making 'scan' UI more solid

This commit is contained in:
Peter Serwylo 2015-04-12 00:14:28 +10:00
parent d7b7af76b7
commit 6f3ca8b9c4
5 changed files with 130 additions and 35 deletions

View File

@ -12,42 +12,50 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/device_name_prefix" android:id="@+id/device_name_prefix"
android:text="Your device is" android:text="@string/swap_bluetooth_your_device"
tools:text="Your device is" android:gravity="center_horizontal"
android:textAlignment="center" style="@style/SwapTheme.BluetoothDeviceList.Heading"
style="@style/SwapTheme.BluetoothDeviceList.Heading" android:paddingTop="10dp" android:paddingTop="10dp"
android:paddingBottom="10dp" android:textSize="24sp"/> android:paddingBottom="10dp"
android:textSize="24sp"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/device_name" android:id="@+id/device_name"
android:text="Pete's Nexus 4" tools:text="Phone v2.0"
tools:text="Pete's Nexus 4" android:gravity="center_horizontal"
android:textAlignment="center" style="@style/SwapTheme.BluetoothDeviceList.Heading"
style="@style/SwapTheme.BluetoothDeviceList.Heading" android:paddingBottom="10dp"/> android:paddingBottom="10dp"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/device_address" android:id="@+id/device_address"
android:text="(01:02:03:ab:cd:ef)"
tools:text="(01:02:03:ab:cd:ef)" tools:text="(01:02:03:ab:cd:ef)"
android:textAlignment="center" android:gravity="center_horizontal"
style="@style/SwapTheme.BluetoothDeviceList.Heading" android:paddingBottom="20dp" android:textSize="24sp"/> style="@style/SwapTheme.BluetoothDeviceList.Heading"
android:paddingBottom="20dp"
android:textSize="24sp"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Select from devices below, or tap here to scan for more devices..." android:text="@string/swap_bluetooth_select_or_scan"
tools:text="Select from devices below, or tap here to scan for more devices..." android:gravity="center_horizontal"
android:textAlignment="center" style="@style/SwapTheme.BluetoothDeviceList.Text"
style="@style/SwapTheme.BluetoothDeviceList.Text" android:paddingLeft="20dp" android:paddingRight="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingBottom="10dp"/> android:paddingBottom="10dp"/>
<android.support.v4.widget.ContentLoadingProgressBar <android.support.v4.widget.ContentLoadingProgressBar
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/loading_indicator"/> android:id="@+id/loading_indicator"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:visibility="gone"
android:indeterminate="true"
style="?android:attr/android:progressBarStyleHorizontal"/>
</LinearLayout> </LinearLayout>

View File

@ -0,0 +1,14 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_scan"
android:title="Scan for devices"
android:titleCondensed="Scan"/>
<item
android:id="@+id/action_cancel"
android:title="Cancel scan"
android:titleCondensed="@string/cancel"
android:visible="false"/>
</menu>

View File

@ -329,4 +329,6 @@
<string name="wifi_warning_public">May work</string> <string name="wifi_warning_public">May work</string>
<string name="wifi_warning_private">Promising</string> <string name="wifi_warning_private">Promising</string>
<string name="wifi_warning_personal">Best bet</string> <string name="wifi_warning_personal">Best bet</string>
<string name="swap_bluetooth_your_device">Your device is</string>
<string name="swap_bluetooth_select_or_scan">Select from devices below, or press \"Scan\" from the menu to find more devices.</string>
</resources> </resources>

View File

@ -46,10 +46,10 @@
<style name="SwapTheme.StartSwap.Text" parent="@style/SwapTheme.StartSwap"> <style name="SwapTheme.StartSwap.Text" parent="@style/SwapTheme.StartSwap">
</style> </style>
<style name="SwapTheme.BluetoothDeviceList" parent="@style/SwapTheme.StartSwap"> <style name="SwapTheme.BluetoothDeviceList" parent="@style/SwapTheme.Wizard">
</style> </style>
<style name="SwapTheme.BluetoothDeviceList.ListItem" parent="AppThemeLightWithDarkActionBar"> <style name="SwapTheme.BluetoothDeviceList.ListItem" parent="AppThemeDark">
</style> </style>
<style name="SwapTheme.BluetoothDeviceList.Text" parent="@style/SwapTheme.BluetoothDeviceList"> <style name="SwapTheme.BluetoothDeviceList.Text" parent="@style/SwapTheme.BluetoothDeviceList">

View File

@ -7,10 +7,14 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.ContentLoadingProgressBar; import android.support.v4.widget.ContentLoadingProgressBar;
import android.util.Log; import android.util.Log;
import android.view.ContextThemeWrapper; import android.view.ContextThemeWrapper;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
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;
@ -29,14 +33,42 @@ import java.util.List;
public class BluetoothDeviceListFragment extends ThemeableListFragment { public class BluetoothDeviceListFragment extends ThemeableListFragment {
private static final String TAG = "org.fdroid.fdroid.views.swap.BluetoothDeviceListFragment"; private static final String TAG = "fdroid.BluetoothList";
private Adapter adapter = null; private Adapter adapter = null;
private MenuItem scanMenuItem;
private MenuItem cancelMenuItem;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setHasOptionsMenu(false); setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.swap_scan, menu);
final int flags = MenuItemCompat.SHOW_AS_ACTION_ALWAYS | MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT;
scanMenuItem = menu.findItem(R.id.action_scan);
scanMenuItem.setVisible(true);
MenuItemCompat.setShowAsAction(scanMenuItem, flags);
cancelMenuItem = menu.findItem(R.id.action_cancel);
cancelMenuItem.setVisible(false);
MenuItemCompat.setShowAsAction(cancelMenuItem, flags);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_scan) {
initiateBluetoothScan();
} else if (item.getItemId() == R.id.action_cancel) {
cancelBluetoothScan();
}
return super.onOptionsItemSelected(item);
} }
@Override @Override
@ -50,7 +82,7 @@ public class BluetoothDeviceListFragment extends ThemeableListFragment {
R.layout.select_local_apps_list_item R.layout.select_local_apps_list_item
); );
populateDeviceList(); populateBondedDevices();
setListAdapter(adapter); setListAdapter(adapter);
setListShown(false); // start out with a progress indicator setListShown(false); // start out with a progress indicator
@ -63,25 +95,54 @@ public class BluetoothDeviceListFragment extends ThemeableListFragment {
if (headerView == null) { if (headerView == null) {
Log.e(TAG, "Could not find header view, although we expected one to exist."); Log.e(TAG, "Could not find header view, although we expected one to exist.");
} else { } else {
headerView.setOnTouchListener(new View.OnTouchListener() { final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
@Override
public boolean onTouch(View v, MotionEvent event) { final TextView deviceName = (TextView)headerView.findViewById(R.id.device_name);
initiateBluetoothScan(); deviceName.setText(bluetooth.getName());
return true;
} final TextView address = (TextView)headerView.findViewById(R.id.device_address);
}); address.setText(bluetooth.getAddress());
} }
return view; return view;
} }
private void cancelBluetoothScan() {
Log.d(TAG, "Cancelling bluetooth scan.");
cancelMenuItem.setVisible(false);
scanMenuItem.setVisible(true);
final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
bluetooth.cancelDiscovery();
getLoadingIndicator().hide();
}
private ContentLoadingProgressBar getLoadingIndicator() {
return ((ContentLoadingProgressBar)getView().findViewById(R.id.loading_indicator));
}
private void initiateBluetoothScan() private void initiateBluetoothScan()
{ {
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter(); Log.d(TAG, "Starting bluetooth scan...");
BroadcastReceiver deviceFoundReceiver = new BroadcastReceiver() {
cancelMenuItem.setVisible(true);
scanMenuItem.setVisible(false);
final ContentLoadingProgressBar loadingBar = getLoadingIndicator();
loadingBar.show();
final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
final BroadcastReceiver deviceFoundReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) { if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "Found bluetooth device: " + device.toString());
boolean exists = false; boolean exists = false;
for (int i = 0; i < adapter.getCount(); i ++) { for (int i = 0; i < adapter.getCount(); i ++) {
if (adapter.getItem(i).getAddress().equals(device.getAddress())) { if (adapter.getItem(i).getAddress().equals(device.getAddress())) {
@ -97,8 +158,18 @@ public class BluetoothDeviceListFragment extends ThemeableListFragment {
} }
}; };
((ContentLoadingProgressBar)getView().findViewById(R.id.loading_indicator)).show(); final BroadcastReceiver scanCompleteReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Scan complete: " + intent.getAction());
loadingBar.hide();
cancelMenuItem.setVisible(false);
scanMenuItem.setVisible(true);
}
};
getActivity().registerReceiver(deviceFoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND)); getActivity().registerReceiver(deviceFoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
getActivity().registerReceiver(scanCompleteReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
if (!bluetooth.startDiscovery()) { if (!bluetooth.startDiscovery()) {
// TODO: Discovery did not start for some reason :( // TODO: Discovery did not start for some reason :(
@ -106,7 +177,7 @@ public class BluetoothDeviceListFragment extends ThemeableListFragment {
} }
} }
private void populateDeviceList() private void populateBondedDevices()
{ {
for (BluetoothDevice device : BluetoothAdapter.getDefaultAdapter().getBondedDevices()) { for (BluetoothDevice device : BluetoothAdapter.getDefaultAdapter().getBondedDevices()) {
adapter.add(device); adapter.add(device);
@ -220,7 +291,7 @@ public class BluetoothDeviceListFragment extends ThemeableListFragment {
TextView addressView = (TextView)view.findViewById(android.R.id.text2); TextView addressView = (TextView)view.findViewById(android.R.id.text2);
TextView descriptionView = (TextView)view.findViewById(R.id.text3); TextView descriptionView = (TextView)view.findViewById(R.id.text3);
nameView.setText(device.getName()); nameView.setText(device.getName() == null ? getString(R.string.unknown) : device.getName());
addressView.setText(device.getAddress()); addressView.setText(device.getAddress());
descriptionView.setText(bondStateToLabel(device.getBondState())); descriptionView.setText(bondStateToLabel(device.getBondState()));