improved filters subscription item style

This commit is contained in:
Mariotaku Lee 2017-01-13 14:51:35 +08:00
parent 7ccf5df99c
commit 15817c8659
6 changed files with 130 additions and 24 deletions

View File

@ -67,6 +67,7 @@ public class ThemeUtils implements Constants {
public static final int DARK_COLOR_THRESHOLD = 128;
public static final int[] ATTRS_TEXT_COLOR_PRIMARY = {android.R.attr.textColorPrimary};
public static final int[] ATTRS_TEXT_COLOR_SECONDARY = {android.R.attr.textColorSecondary};
private ThemeUtils() {
throw new AssertionError("ThemeUtils should never be instantiated");
@ -205,6 +206,15 @@ public class ThemeUtils implements Constants {
}
}
public static int getTextColorSecondary(final Context context) {
final TypedArray a = context.obtainStyledAttributes(ATTRS_TEXT_COLOR_SECONDARY);
try {
return a.getColor(0, Color.TRANSPARENT);
} finally {
a.recycle();
}
}
public static int getThemeBackgroundColor(final Context context) {
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.colorBackground});

View File

@ -279,9 +279,23 @@ class WebLinkHandlerActivity : Activity(), Constants {
companion object {
val TWITTER_RESERVED_PATHS = arrayOf("about", "account", "accounts", "activity", "all", "announcements", "anywhere", "api_rules", "api_terms", "apirules", "apps", "auth", "badges", "blog", "business", "buttons", "contacts", "devices", "direct_messages", "download", "downloads", "edit_announcements", "faq", "favorites", "find_sources", "find_users", "followers", "following", "friend_request", "friendrequest", "friends", "goodies", "help", "home", "im_account", "inbox", "invitations", "invite", "jobs", "list", "login", "logo", "logout", "me", "mentions", "messages", "mockview", "newtwitter", "notifications", "nudge", "oauth", "phoenix_search", "positions", "privacy", "public_timeline", "related_tweets", "replies", "retweeted_of_mine", "retweets", "retweets_by_others", "rules", "saved_searches", "search", "sent", "settings", "share", "signup", "signin", "similar_to", "statistics", "terms", "tos", "translate", "trends", "tweetbutton", "twttr", "update_discoverability", "users", "welcome", "who_to_follow", "widgets", "zendesk_auth", "media_signup")
val TWITTER_RESERVED_PATHS = arrayOf("about", "account", "accounts", "activity", "all",
"announcements", "anywhere", "api_rules", "api_terms", "apirules", "apps", "auth",
"badges", "blog", "business", "buttons", "contacts", "devices", "direct_messages",
"download", "downloads", "edit_announcements", "faq", "favorites", "find_sources",
"find_users", "followers", "following", "friend_request", "friendrequest", "friends",
"goodies", "help", "home", "im_account", "inbox", "invitations", "invite", "jobs",
"list", "login", "logo", "logout", "me", "mentions", "messages", "mockview",
"newtwitter", "notifications", "nudge", "oauth", "phoenix_search", "positions",
"privacy", "public_timeline", "related_tweets", "replies", "retweeted_of_mine",
"retweets", "retweets_by_others", "rules", "saved_searches", "search", "sent",
"settings", "share", "signup", "signin", "similar_to", "statistics", "terms", "tos",
"translate", "trends", "tweetbutton", "twttr", "update_discoverability", "users",
"welcome", "who_to_follow", "widgets", "zendesk_auth", "media_signup")
val FANFOU_RESERVED_PATHS = arrayOf("home", "privatemsg", "finder", "browse", "search", "settings", "message", "mentions", "favorites", "friends", "followers", "sharer", "photo", "album", "paipai", "q", "userview", "dialogue")
val FANFOU_RESERVED_PATHS = arrayOf("home", "privatemsg", "finder", "browse", "search",
"settings", "message", "mentions", "favorites", "friends", "followers", "sharer",
"photo", "album", "paipai", "q", "userview", "dialogue")
private val AUTHORITY_TWITTER_COM = "twitter.com"

View File

@ -25,23 +25,25 @@ import android.content.Context
import android.content.DialogInterface
import android.content.DialogInterface.OnClickListener
import android.database.Cursor
import android.graphics.PorterDuff
import android.net.Uri
import android.os.Bundle
import android.support.v4.app.LoaderManager
import android.support.v4.content.ContextCompat
import android.support.v4.content.CursorLoader
import android.support.v4.content.Loader
import android.support.v4.view.ViewCompat
import android.support.v4.widget.SimpleCursorAdapter
import android.support.v7.app.AlertDialog
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextUtils
import android.view.ActionMode
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.*
import android.widget.AbsListView
import android.widget.AbsListView.MultiChoiceModeListener
import android.widget.AutoCompleteTextView
import android.widget.ListView
import android.widget.TextView
import kotlinx.android.synthetic.main.fragment_content_listview.*
import org.mariotaku.ktextension.setGroupAvailability
import org.mariotaku.sqliteqb.library.Columns
@ -57,8 +59,11 @@ import org.mariotaku.twidere.extension.selectNone
import org.mariotaku.twidere.extension.updateSelectionItems
import org.mariotaku.twidere.fragment.AbsContentListViewFragment
import org.mariotaku.twidere.fragment.BaseDialogFragment
import org.mariotaku.twidere.model.`FiltersData$BaseItemCursorIndices`
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.text.style.EmojiSpan
import org.mariotaku.twidere.util.ParseUtils
import org.mariotaku.twidere.util.ThemeUtils
import org.mariotaku.twidere.util.Utils
@ -73,7 +78,9 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
private var actionMode: ActionMode? = null
abstract val contentUri: Uri
protected abstract val contentUri: Uri
protected abstract val contentColumns: Array<String>
protected open val sortOrder: String? = "${Filters.SOURCE} >= 0"
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
@ -141,6 +148,12 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
override fun onItemCheckedStateChanged(mode: ActionMode, position: Int, id: Long,
checked: Boolean) {
val adapter = this.adapter
if (adapter is SelectableItemAdapter) {
if (!adapter.isSelectable(position) && checked) {
listView.setItemChecked(position, false)
}
}
updateTitle(mode)
mode.invalidate()
}
@ -165,7 +178,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor?> {
return CursorLoader(activity, contentUri, contentColumns, null, null, null)
return CursorLoader(activity, contentUri, contentColumns, null, null, sortOrder)
}
override fun onLoadFinished(loader: Loader<Cursor?>, data: Cursor?) {
@ -211,7 +224,6 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
context.contentResolver.delete(contentUri, where.sql, Array(ids.size) { ids[it].toString() })
}
protected abstract val contentColumns: Array<String>
private fun updateTitle(mode: ActionMode?) {
if (listView == null || mode == null || activity == null) return
@ -276,18 +288,52 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
}
interface SelectableItemAdapter {
fun isSelectable(position: Int): Boolean
}
private class FilterListAdapter(
context: Context
) : SimpleCursorAdapter(context, R.layout.simple_list_item_activated_1, null,
from, to, 0) {
companion object {
emptyArray(), intArrayOf(), 0), SelectableItemAdapter {
private val from = arrayOf(Filters.VALUE)
private var indices: `FiltersData$BaseItemCursorIndices`? = null
private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context)
private val to = intArrayOf(android.R.id.text1)
override fun swapCursor(c: Cursor?): Cursor? {
val old = super.swapCursor(c)
if (c != null) {
indices = `FiltersData$BaseItemCursorIndices`(c)
}
return old
}
override fun bindView(view: View, context: Context, cursor: Cursor) {
super.bindView(view, context, cursor)
val indices = this.indices!!
val text1 = view.findViewById(android.R.id.text1) as TextView
val ssb = SpannableStringBuilder(cursor.getString(indices.value))
if (cursor.getLong(indices.source) >= 0) {
val start = ssb.length
ssb.append("*")
val end = start + 1
val drawable = ContextCompat.getDrawable(context, R.drawable.ic_action_sync)
drawable.setColorFilter(secondaryTextColor, PorterDuff.Mode.SRC_ATOP)
ssb.setSpan(EmojiSpan(drawable), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
text1.text = ssb
}
override fun isSelectable(position: Int): Boolean {
val cursor = this.cursor ?: return false
if (cursor.moveToPosition(position)) {
return cursor.getLong(indices!!.source) < 0
}
return false
}
}
companion object {

View File

@ -4,10 +4,14 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.graphics.PorterDuff
import android.net.Uri
import android.os.Bundle
import android.support.v4.app.FragmentActivity
import android.support.v4.content.ContextCompat
import android.support.v4.widget.SimpleCursorAdapter
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
@ -28,9 +32,11 @@ import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.`FiltersData$UserItemCursorIndices`
import org.mariotaku.twidere.model.analyzer.PurchaseFinished
import org.mariotaku.twidere.provider.TwidereDataStore
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.text.style.EmojiSpan
import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.ContentValuesCreator
import org.mariotaku.twidere.util.ThemeUtils
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
@ -38,17 +44,14 @@ import javax.inject.Inject
class FilteredUsersFragment : BaseFiltersFragment() {
public override val contentColumns: Array<String>
get() = TwidereDataStore.Filters.Users.COLUMNS
override val contentUri: Uri
get() = TwidereDataStore.Filters.Users.CONTENT_URI
override val contentUri: Uri = Filters.Users.CONTENT_URI
override val contentColumns: Array<String> = Filters.Users.COLUMNS
override val sortOrder: String? = "${Filters.Users.SOURCE} >= 0"
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_SELECT_USER -> {
@ -56,10 +59,10 @@ class FilteredUsersFragment : BaseFiltersFragment() {
val user = data!!.getParcelableExtra<ParcelableUser>(EXTRA_USER)
val values = ContentValuesCreator.createFilteredUser(user)
val resolver = context.contentResolver
val where = Expression.equalsArgs(TwidereDataStore.Filters.Users.USER_KEY).sql
val where = Expression.equalsArgs(Filters.Users.USER_KEY).sql
val whereArgs = arrayOf(user.key.toString())
resolver.delete(TwidereDataStore.Filters.Users.CONTENT_URI, where, whereArgs)
resolver.insert(TwidereDataStore.Filters.Users.CONTENT_URI, values)
resolver.delete(Filters.Users.CONTENT_URI, where, whereArgs)
resolver.insert(Filters.Users.CONTENT_URI, values)
}
REQUEST_IMPORT_BLOCKS_SELECT_ACCOUNT -> {
if (resultCode != FragmentActivity.RESULT_OK) return
@ -137,7 +140,7 @@ class FilteredUsersFragment : BaseFiltersFragment() {
class FilterUsersListAdapter(
context: Context
) : SimpleCursorAdapter(context, R.layout.list_item_two_line, null,
emptyArray(), IntArray(0), 0) {
emptyArray(), IntArray(0), 0), SelectableItemAdapter {
@Inject
lateinit var userColorNameManager: UserColorNameManager
@ -147,6 +150,7 @@ class FilteredUsersFragment : BaseFiltersFragment() {
private val nameFirst: Boolean
private var indices: `FiltersData$UserItemCursorIndices`? = null
private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context)
init {
GeneralComponentHelper.build(context).inject(this)
@ -168,6 +172,17 @@ class FilteredUsersFragment : BaseFiltersFragment() {
val displayName = userColorNameManager.getDisplayName(userId, name, screenName,
nameFirst)
text1.text = displayName
val ssb = SpannableStringBuilder(displayName)
if (cursor.getLong(indices.source) >= 0) {
val start = ssb.length
ssb.append("*")
val end = start + 1
val drawable = ContextCompat.getDrawable(context, R.drawable.ic_action_sync)
drawable.setColorFilter(secondaryTextColor, PorterDuff.Mode.SRC_ATOP)
ssb.setSpan(EmojiSpan(drawable), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
text1.text = ssb
text2.text = userId.host
}
@ -179,6 +194,13 @@ class FilteredUsersFragment : BaseFiltersFragment() {
return old
}
override fun isSelectable(position: Int): Boolean {
val cursor = this.cursor ?: return false
if (cursor.moveToPosition(position)) {
return cursor.getLong(indices!!.source) < 0
}
return false
}
}
}

View File

@ -902,4 +902,5 @@
<string name="title_subscription_url">URL</string>
<string name="title_filters_subscription_invalid">Invalid subscription</string>
<string name="title_filters_subscription_url">URL</string>
<string name="label_filters_subscription">Subscription</string>
</resources>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
<title>ic_action_sync-mdpi</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Action-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="ic_action_sync-mdpi">
<path d="M16,8 L16,5 L12,9 L16,13 L16,10 C19.31,10 22,12.69 22,16 C22,17.01 21.75,17.97 21.3,18.8 L22.76,20.26 C23.54,19.03 24,17.57 24,16 C24,11.58 20.42,8 16,8 L16,8 Z M16,22 C12.69,22 10,19.31 10,16 C10,14.99 10.25,14.03 10.7,13.2 L9.24,11.74 C8.46,12.97 8,14.43 8,16 C8,20.42 11.58,24 16,24 L16,27 L20,23 L16,19 L16,22 Z" id="Shape" fill="#FFFFFF"></path>
<polygon id="Shape" points="4 4 28 4 28 28 4 28"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 960 B