summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstom79 <tschneider.ac@gmail.com>2018-10-26 17:14:08 +0200
committerstom79 <tschneider.ac@gmail.com>2018-10-26 17:14:08 +0200
commit1463a8db1563f5f97ded8f0ae1a61c35ff0fa09b (patch)
treec1ef9c958cf7790bfaa971dbdeacb8fb8ac37d8a
parent5a02afda11939198b03941ec0fc3e58ee400e73f (diff)
parent202952d6bd785f92db1f49eef4e6b02f27cbeda6 (diff)
Merge branch 'bug_fixes' into develop
-rw-r--r--app/build.gradle6
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/activities/AboutActivity.java9
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/activities/EditProfileActivity.java4
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/activities/LoginActivity.java3
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/activities/RemoteFollowActivity.java4
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowConversationActivity.java2
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java4
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/client/API.java8
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/client/HttpsConnection.java1
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/drawers/ConversationDecoration.java16
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java4
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java5
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java73
-rw-r--r--app/src/main/java/fr/gouv/etalab/mastodon/services/NetworkStateReceiver.java3
-rw-r--r--app/src/main/res/layout/fragment_settings_notifications.xml1
-rw-r--r--app/src/main/res/values/styles.xml2
16 files changed, 85 insertions, 60 deletions
diff --git a/app/build.gradle b/app/build.gradle
index a22ff6d99..233b41788 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "fr.gouv.etalab.mastodon"
minSdkVersion 15
targetSdkVersion 28
- versionCode 164
- versionName "1.17.7"
+ versionCode 165
+ versionName "1.17.8"
}
flavorDimensions "default"
buildTypes {
@@ -45,7 +45,7 @@ allprojects {
ext.supportLibraryVersion = '28.0.0'
ext.glideLibraryVersion = '4.8.0'
ext.conscryptLibraryVersion = '1.3.0'
-ext.evernoteLibraryVersion = '1.3.0-alpha07'
+ext.evernoteLibraryVersion = '1.3.0-alpha08'
ext.gsonLibraryVersion = '2.8.2'
ext.guavaLibraryVersion = '24.1-android'
ext.photoViewLibraryVersion = '2.0.0'
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/AboutActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/AboutActivity.java
index ab091175b..5260cda70 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/AboutActivity.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/AboutActivity.java
@@ -173,15 +173,6 @@ public class AboutActivity extends BaseActivity implements OnRetrieveRemoteAccou
}
});
- if( theme == Helper.THEME_LIGHT) {
- about_code.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- about_thekinrar.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- about_trunk.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- about_translation.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- about_license.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- about_support.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- paypal.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- }
TextView about_website = findViewById(R.id.about_website);
about_website.setOnClickListener(new View.OnClickListener() {
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/EditProfileActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/EditProfileActivity.java
index 83d516183..40291b793 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/EditProfileActivity.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/EditProfileActivity.java
@@ -206,9 +206,7 @@ public class EditProfileActivity extends BaseActivity implements OnRetrieveAccou
set_lock_account.setEnabled(false);
new RetrieveAccountInfoAsyncTask(getApplicationContext(), EditProfileActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- if( theme == Helper.THEME_LIGHT) {
- set_profile_save.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- }
+
}
@Override
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/LoginActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/LoginActivity.java
index b2fbbdc91..e686ab9be 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/LoginActivity.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/LoginActivity.java
@@ -140,9 +140,6 @@ public class LoginActivity extends BaseActivity {
login_passwd = findViewById(R.id.login_passwd);
- if (theme == Helper.THEME_LIGHT) {
- connectionButton.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- }
login_instance.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/RemoteFollowActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/RemoteFollowActivity.java
index 7f8434b24..5f2f6d1a7 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/RemoteFollowActivity.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/RemoteFollowActivity.java
@@ -122,9 +122,7 @@ public class RemoteFollowActivity extends BaseActivity implements OnRetrieveRemo
loader = findViewById(R.id.loader);
lv_account = findViewById(R.id.lv_account);
rf_no_result = findViewById(R.id.rf_no_result);
- if( theme == Helper.THEME_LIGHT) {
- rf_search.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- }
+
isLoadingInstance = false;
ActionBar actionBar = getSupportActionBar();
if( actionBar != null) {
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowConversationActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowConversationActivity.java
index d98efc1b6..6d8a35cfe 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowConversationActivity.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowConversationActivity.java
@@ -336,7 +336,7 @@ public class ShowConversationActivity extends BaseActivity implements OnRetrieve
mLayoutManager = new LinearLayoutManager(this);
lv_status.setLayoutManager(mLayoutManager);
- lv_status.addItemDecoration(new ConversationDecoration(ShowConversationActivity.this,position));
+ lv_status.addItemDecoration(new ConversationDecoration(ShowConversationActivity.this));
lv_status.setAdapter(statusListAdapter);
if( isRefreshed){
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java
index 5a3f3f4a0..fb99aaa94 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java
@@ -656,9 +656,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
if( restored != -1 ){
restoreToot(restored);
}
- if( theme == Helper.THEME_LIGHT) {
- toot_it.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
- }
+
}
@Override
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java
index c41c390ac..2d4f31017 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java
@@ -16,7 +16,6 @@ package fr.gouv.etalab.mastodon.client;
import android.content.Context;
import android.content.SharedPreferences;
-
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -27,7 +26,6 @@ import java.lang.*;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
-import java.text.Format;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
@@ -729,8 +727,12 @@ public class API {
*/
public APIResponse searchPeertube(String instance, String query) {
HashMap<String, String> params = new HashMap<>();
- params.put("search", query);
params.put("count", "50");
+ try {
+ params.put("search", URLEncoder.encode(query, "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ params.put("search", query);
+ }
List<Peertube> peertubes = new ArrayList<>();
try {
HttpsConnection httpsConnection = new HttpsConnection(context);
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/HttpsConnection.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/HttpsConnection.java
index 5304e4989..d89c55d29 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/client/HttpsConnection.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/HttpsConnection.java
@@ -118,6 +118,7 @@ public class HttpsConnection {
@SuppressWarnings("ConstantConditions")
public String get(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
+
if( urlConnection.startsWith("https://")) {
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ConversationDecoration.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ConversationDecoration.java
index f256126d8..8575a1bf6 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ConversationDecoration.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ConversationDecoration.java
@@ -21,7 +21,6 @@ import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
-import android.util.Log;
import android.view.View;
import fr.gouv.etalab.mastodon.R;
@@ -36,11 +35,9 @@ public class ConversationDecoration extends RecyclerView.ItemDecoration{
private Drawable divider;
private Context context;
- private int statusOpenedPosition;
- public ConversationDecoration(Context context, int statusOpenedPosition){
+ public ConversationDecoration(Context context){
divider = ContextCompat.getDrawable(context,R.drawable.line_divider);
- this.statusOpenedPosition = statusOpenedPosition;
this.context = context;
}
@@ -60,10 +57,10 @@ public class ConversationDecoration extends RecyclerView.ItemDecoration{
StatusListAdapter adapter = (StatusListAdapter) parent.getAdapter();
int position = parent.getChildAdapterPosition(child);
+ assert adapter != null;
Status status = adapter.getItem(position);
- int top = 0;
- int bottom = 0;
+ int top, bottom;
if( status != null){
Status statusBefore = null;
if( position > 0)
@@ -75,11 +72,12 @@ public class ConversationDecoration extends RecyclerView.ItemDecoration{
statusAfter = adapter.getItem(position + 1);
bottom = (statusAfter != null && status.getId().equals(statusAfter.getIn_reply_to_id()) )?
child.getBottom():child.getTop()+offSet;
- if( position == 0)
+ if( position == 0 && childCount > 1)
top = bottom - (int)Helper.convertDpToPixel(28, context);
+ divider.setBounds(left, top, right, bottom);
+ divider.draw(canvas);
}
- divider.setBounds(left, top, right, bottom);
- divider.draw(canvas);
+
}
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java
index 9861d8d4c..8418e4b59 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java
@@ -354,7 +354,9 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
}
public Status getItem(int position){
- return statuses.get(position);
+ if( statuses.size() > position)
+ return statuses.get(position);
+ else return null;
}
@Override
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java
index 9740064ca..68e830729 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java
@@ -570,6 +570,11 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
if( statuses != null && statuses.size() > 0)
retrieveMissingToots(statuses.get(0).getId());
}
+ }else if (type == RetrieveFeedsAsyncTask.Type.DIRECT){
+ if( getUserVisibleHint() ){
+ if( statuses != null && statuses.size() > 0)
+ retrieveMissingToots(statuses.get(0).getId());
+ }
}else if (type == RetrieveFeedsAsyncTask.Type.HOME){
statusListAdapter.updateMuted(mutedAccount);
if( statuses != null && statuses.size() > 0)
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java b/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java
index 9f01bfee0..72cee186d 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java
@@ -34,7 +34,6 @@ import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
-
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
@@ -42,6 +41,8 @@ import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
+import com.koushikdutta.async.callback.CompletedCallback;
+import com.koushikdutta.async.future.Future;
import com.koushikdutta.async.http.AsyncHttpClient;
import com.koushikdutta.async.http.AsyncHttpRequest;
import com.koushikdutta.async.http.Headers;
@@ -50,7 +51,9 @@ import com.koushikdutta.async.http.WebSocket;
import org.json.JSONException;
import org.json.JSONObject;
+import java.util.HashMap;
import java.util.List;
+import java.util.concurrent.ExecutionException;
import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.activities.MainActivity;
@@ -81,13 +84,14 @@ public class LiveNotificationService extends Service implements NetworkStateRece
boolean backgroundProcess;
private static Thread thread;
private NetworkStateReceiver networkStateReceiver;
+ private static HashMap<String, Future<WebSocket>> webSocketFutures = new HashMap<>();
public void onCreate() {
super.onCreate();
networkStateReceiver = new NetworkStateReceiver();
networkStateReceiver.addListener(this);
+ registerReceiver(networkStateReceiver, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
startStream();
- this.registerReceiver(networkStateReceiver, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
}
private void startStream(){
@@ -96,20 +100,23 @@ public class LiveNotificationService extends Service implements NetworkStateRece
boolean liveNotifications = sharedpreferences.getBoolean(Helper.SET_LIVE_NOTIFICATIONS, true);
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
if( liveNotifications ){
- if( thread != null && thread.isAlive())
- thread.interrupt();
- thread = new Thread() {
- @Override
- public void run() {
- List<Account> accountStreams = new AccountDAO(getApplicationContext(), db).getAllAccount();
- if (accountStreams != null) {
- for (final Account accountStream : accountStreams) {
- taks(accountStream);
+ if( thread == null || !thread.isAlive()){
+ if(thread != null)
+ thread.interrupt();
+ thread = new Thread() {
+ @Override
+ public void run() {
+ List<Account> accountStreams = new AccountDAO(getApplicationContext(), db).getAllAccount();
+ if (accountStreams != null) {
+ for (final Account accountStream : accountStreams) {
+ taks(accountStream);
+ }
}
}
- }
- };
- thread.start();
+ };
+ thread.start();
+ }
+
}
}
@@ -129,7 +136,7 @@ public class LiveNotificationService extends Service implements NetworkStateRece
public void onDestroy() {
super.onDestroy();
networkStateReceiver.removeListener(this);
- this.unregisterReceiver(networkStateReceiver);
+ unregisterReceiver(networkStateReceiver);
}
@Nullable
@@ -147,7 +154,7 @@ public class LiveNotificationService extends Service implements NetworkStateRece
}
private void restart(){
- Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
+ Intent restartServiceIntent = new Intent(LiveNotificationService.this, LiveNotificationService.class);
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
@@ -158,17 +165,25 @@ public class LiveNotificationService extends Service implements NetworkStateRece
}
private void taks(Account account) {
-
-
if (account != null) {
Headers headers = new Headers();
headers.add("Authorization", "Bearer " + account.getToken());
headers.add("Connection", "Keep-Alive");
headers.add("method", "GET");
headers.add("scheme", "https");
- Uri url = Uri.parse("wss://" + account.getInstance() + "/api/v1/streaming/?stream=user&access_token=" + account.getToken());
+ String urlKey = "wss://" + account.getInstance() + "/api/v1/streaming/?stream=user&access_token=" + account.getToken();
+ Uri url = Uri.parse(urlKey);
AsyncHttpRequest.setDefaultHeaders(headers, url);
- AsyncHttpClient.getDefaultInstance().websocket("wss://" + account.getInstance() + "/api/v1/streaming/?stream=user&access_token=" + account.getToken(), "wss", new AsyncHttpClient.WebSocketConnectCallback() {
+ if( webSocketFutures.containsKey(urlKey) ){
+ try {
+ webSocketFutures.get(urlKey).get().close();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ Future<WebSocket> webSocketFuture = AsyncHttpClient.getDefaultInstance().websocket("wss://" + account.getInstance() + "/api/v1/streaming/?stream=user&access_token=" + account.getToken(), "wss", new AsyncHttpClient.WebSocketConnectCallback() {
@Override
public void onCompleted(Exception ex, WebSocket webSocket) {
if (ex != null) {
@@ -183,8 +198,26 @@ public class LiveNotificationService extends Service implements NetworkStateRece
} catch (JSONException ignored) {}
}
});
+
+ webSocket.setClosedCallback(new CompletedCallback() {
+ @Override
+ public void onCompleted(Exception ex) {
+ if( ex != null){
+ webSocket.close();
+ if( webSocketFutures != null && webSocketFutures.containsKey(urlKey))
+ webSocketFutures.remove(urlKey);
+ taks(account);
+ if( networkStateReceiver != null && networkStateReceiver.listeners.size() == 0){
+ networkStateReceiver.addListener(LiveNotificationService.this);
+ registerReceiver(networkStateReceiver, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
+ }
+ }
+
+ }
+ });
}
});
+ webSocketFutures.put(urlKey, webSocketFuture);
}
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/services/NetworkStateReceiver.java b/app/src/main/java/fr/gouv/etalab/mastodon/services/NetworkStateReceiver.java
index a92c53c69..9f9b1e49d 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/services/NetworkStateReceiver.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/services/NetworkStateReceiver.java
@@ -22,6 +22,7 @@ import android.net.NetworkInfo;
import java.util.HashSet;
import java.util.Set;
+
/**
* Original work from https://stackoverflow.com/a/25873554
*
@@ -36,6 +37,7 @@ public class NetworkStateReceiver extends BroadcastReceiver {
connected = null;
}
+ @Override
public void onReceive(Context context, Intent intent) {
if(intent == null || intent.getExtras() == null)
return;
@@ -53,6 +55,7 @@ public class NetworkStateReceiver extends BroadcastReceiver {
notifyStateToAll();
}
+
private void notifyStateToAll() {
for(NetworkStateReceiverListener listener : listeners)
notifyState(listener);
diff --git a/app/src/main/res/layout/fragment_settings_notifications.xml b/app/src/main/res/layout/fragment_settings_notifications.xml
index dbdf991c4..f9da4113a 100644
--- a/app/src/main/res/layout/fragment_settings_notifications.xml
+++ b/app/src/main/res/layout/fragment_settings_notifications.xml
@@ -65,7 +65,6 @@
android:gravity="center"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:tint="@android:color/white"
- android:textColor="@color/white"
android:text="@string/set_notif_sound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index bacead113..190d3e347 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -91,7 +91,7 @@
<item name="android:background">@drawable/menu_selector</item>
</style>
<style name="ButtonColor" parent="Base.Widget.AppCompat.Button">
- <item name="android:textColor">@color/mastodonC4</item>
+ <item name="android:textColor">@color/white</item>
<item name="android:background">@drawable/button_selector</item>
</style>
<style name="PopupMenu" parent="@android:style/Widget.PopupMenu">