diff --git a/src/main/res/layout/layout_apps.xml b/src/main/res/layout/layout_apps.xml
index f84d4bbd..0d75f23d 100644
--- a/src/main/res/layout/layout_apps.xml
+++ b/src/main/res/layout/layout_apps.xml
@@ -32,8 +32,17 @@
android:layout_marginEnd="6dp"
android:layout_marginRight="6dp"/>
-
+
+
+
+
\ No newline at end of file
diff --git a/src/main/scala/com/github/shadowsocks/AppManager.scala b/src/main/scala/com/github/shadowsocks/AppManager.scala
index aca7aca4..ebdc091e 100644
--- a/src/main/scala/com/github/shadowsocks/AppManager.scala
+++ b/src/main/scala/com/github/shadowsocks/AppManager.scala
@@ -41,7 +41,6 @@ package com.github.shadowsocks
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, InputStream}
-import android.app.ProgressDialog
import android.content.pm.PackageManager
import android.content.{ClipData, ClipboardManager, Context, SharedPreferences}
import android.graphics.{Bitmap, PixelFormat}
@@ -112,7 +111,6 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
var apps: Array[ProxiedApp] = null
var appListView: ListView = null
var overlay: TextView = null
- var progressDialog: ProgressDialog = null
var adapter: ListAdapter = null
var appsLoaded: Boolean = false
@@ -295,14 +293,37 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
bypassSwitch.setChecked(ShadowsocksApplication.settings.getBoolean(Key.isBypassApps, false))
appListView = findViewById(R.id.applistview).asInstanceOf[ListView]
+ appListView.setOnScrollListener(new AbsListView.OnScrollListener {
+ var visible = false
+ def onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int,
+ totalItemCount: Int) {
+ if (visible) {
+ val name: String = apps(firstVisibleItem).name
+ if (name != null && name.length > 1) {
+ overlay.setText(apps(firstVisibleItem).name.substring(0, 1))
+ } else {
+ overlay.setText("*")
+ }
+ overlay.setVisibility(View.VISIBLE)
+ }
+ }
+ def onScrollStateChanged(view: AbsListView, scrollState: Int) {
+ visible = true
+ if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
+ overlay.setVisibility(View.INVISIBLE)
+ }
+ }
+ })
}
protected override def onResume() {
super.onResume()
Future {
- handler.post(loadStartRunnable)
if (!appsLoaded) loadApps()
- handler.post(loadFinishRunnable)
+ handler.post(() => {
+ appListView.setAdapter(adapter)
+ Utils.crossFade(AppManager.this, findViewById(R.id.loading), appListView)
+ })
}
}
@@ -319,44 +340,6 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
edit.apply
}
- val loadStartRunnable = new Runnable {
- override def run() {
- progressDialog = ProgressDialog
- .show(AppManager.this, "", getString(R.string.loading), true, true)
- }
- }
-
- val loadFinishRunnable = new Runnable {
- override def run() = {
- appListView.setAdapter(adapter)
- appListView.setOnScrollListener(new AbsListView.OnScrollListener {
- def onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int,
- totalItemCount: Int) {
- if (visible) {
- val name: String = apps(firstVisibleItem).name
- if (name != null && name.length > 1) {
- overlay.setText(apps(firstVisibleItem).name.substring(0, 1))
- } else {
- overlay.setText("*")
- }
- overlay.setVisibility(View.VISIBLE)
- }
- }
- def onScrollStateChanged(view: AbsListView, scrollState: Int) {
- visible = true
- if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
- overlay.setVisibility(View.INVISIBLE)
- }
- }
- var visible = false
- })
- if (progressDialog != null) {
- progressDialog.dismiss()
- progressDialog = null
- }
- }
- }
-
var handler: Handler = null
class AppIconDownloader(context: Context, connectTimeout: Int, readTimeout: Int)
diff --git a/src/main/scala/com/github/shadowsocks/utils/Utils.scala b/src/main/scala/com/github/shadowsocks/utils/Utils.scala
index e80012a4..f2d5c981 100644
--- a/src/main/scala/com/github/shadowsocks/utils/Utils.scala
+++ b/src/main/scala/com/github/shadowsocks/utils/Utils.scala
@@ -42,6 +42,7 @@ import java.io._
import java.net._
import java.security.MessageDigest
+import android.animation.{AnimatorListenerAdapter, Animator}
import android.app.ActivityManager
import android.content.pm.{ApplicationInfo, PackageManager}
import android.content.{Context, Intent}
@@ -142,6 +143,16 @@ object Utils {
toast
}
+ def crossFade(context: Context, from: View, to: View) {
+ def shortAnimTime = context.getResources.getInteger(android.R.integer.config_shortAnimTime)
+ to.setAlpha(0)
+ to.setVisibility(View.VISIBLE)
+ to.animate().alpha(1).setDuration(shortAnimTime)
+ from.animate().alpha(0).setDuration(shortAnimTime).setListener(new AnimatorListenerAdapter {
+ override def onAnimationEnd(animation: Animator) = from.setVisibility(View.GONE)
+ })
+ }
+
// Blocked > 3 seconds
def toggleAirplaneMode(context: Context) {
if (Build.VERSION.SDK_INT >= 17) {