rewriting users and lists picker (WIP)

This commit is contained in:
Mariotaku Lee 2017-01-29 21:34:22 +08:00
parent 95f80b222e
commit 3129a25c55
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
8 changed files with 321 additions and 175 deletions

View File

@ -376,11 +376,20 @@
</intent-filter>
</activity>
<activity
android:name=".activity.UserListSelectorActivity"
android:name=".activity.UserSelectorActivity"
android:label="@string/select_user_list"
android:theme="@style/Theme.Twidere.Dialog">
<intent-filter>
<action android:name="org.mariotaku.twidere.SELECT_USER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name=".activity.UserListSelectorActivity"
android:label="@string/select_user"
android:theme="@style/Theme.Twidere.Dialog">
<intent-filter>
<action android:name="org.mariotaku.twidere.SELECT_USER_LIST"/>
<category android:name="android.intent.category.DEFAULT"/>

View File

@ -36,32 +36,26 @@ import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.activity_user_list_selector.*
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.http.HttpResponseCode
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.adapter.SimpleParcelableUserListsAdapter
import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter
import org.mariotaku.twidere.adapter.UserAutoCompleteAdapter
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.fragment.CreateUserListDialogFragment
import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.SingleResponse
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.message.UserListCreatedEvent
import org.mariotaku.twidere.model.util.ParcelableUserListUtils
import org.mariotaku.twidere.model.util.ParcelableUserUtils
import org.mariotaku.twidere.util.AsyncTaskUtils
import org.mariotaku.twidere.util.DataStoreUtils.getAccountScreenName
import org.mariotaku.twidere.util.MicroBlogAPIFactory
import org.mariotaku.twidere.util.ParseUtils
import java.util.*
class UserListSelectorActivity : BaseActivity(), OnClickListener, OnItemClickListener {
private lateinit var userListsAdapter: SimpleParcelableUserListsAdapter
private lateinit var usersAdapter: SimpleParcelableUsersAdapter
private var screenName: String? = null
@ -79,43 +73,19 @@ class UserListSelectorActivity : BaseActivity(), OnClickListener, OnItemClickLis
screenName = savedInstanceState.getString(EXTRA_SCREEN_NAME)
}
val selectingUser = isSelectingUser
setTitle(if (selectingUser) R.string.select_user else R.string.select_user_list)
if (!isEmpty(screenName)) {
if (selectingUser) {
searchUser(screenName!!)
} else {
getUserLists(screenName)
}
getUserLists(screenName)
}
val adapter = UserAutoCompleteAdapter(this)
adapter.accountKey = accountKey
editScreenName.setAdapter(adapter)
editScreenName.setText(screenName)
userListsAdapter = SimpleParcelableUserListsAdapter(this)
usersAdapter = SimpleParcelableUsersAdapter(this)
userListsList.adapter = userListsAdapter
usersList.adapter = usersAdapter
userListsList.onItemClickListener = this
usersList.onItemClickListener = this
screenNameConfirm.setOnClickListener(this)
createList.setOnClickListener(this)
if (selectingUser) {
usersListContainer.visibility = View.VISIBLE
userListsContainer.visibility = View.GONE
} else {
usersListContainer.visibility = if (isEmpty(screenName)) View.VISIBLE else View.GONE
userListsContainer.visibility = if (isEmpty(screenName)) View.GONE else View.VISIBLE
}
}
override fun onClick(v: View) {
when (v.id) {
R.id.screenNameConfirm -> {
val screen_name = ParseUtils.parseString(editScreenName.text)
if (isEmpty(screen_name)) return
searchUser(screen_name)
}
R.id.createList -> {
val f = CreateUserListDialogFragment()
val args = Bundle()
@ -127,31 +97,11 @@ class UserListSelectorActivity : BaseActivity(), OnClickListener, OnItemClickLis
}
override fun onItemClick(view: AdapterView<*>, child: View, position: Int, id: Long) {
val view_id = view.id
val list = view as ListView
if (view_id == R.id.usersList) {
val user = usersAdapter.getItem(position - list.headerViewsCount) ?: return
if (isSelectingUser) {
val data = Intent()
data.setExtrasClassLoader(classLoader)
data.putExtra(EXTRA_USER, user)
setResult(Activity.RESULT_OK, data)
finish()
} else {
getUserLists(user.screen_name)
}
} else if (view_id == R.id.userListsList) {
val data = Intent()
data.putExtra(EXTRA_USER_LIST, userListsAdapter.getItem(position - list.headerViewsCount))
setResult(Activity.RESULT_OK, data)
finish()
}
}
fun setUsersData(data: List<ParcelableUser>) {
usersAdapter.setData(data, true)
usersListContainer.visibility = View.VISIBLE
userListsContainer.visibility = View.GONE
val data = Intent()
data.putExtra(EXTRA_USER_LIST, userListsAdapter.getItem(position - list.headerViewsCount))
setResult(Activity.RESULT_OK, data)
finish()
}
override fun onSaveInstanceState(outState: Bundle) {
@ -177,14 +127,8 @@ class UserListSelectorActivity : BaseActivity(), OnClickListener, OnItemClickLis
private val isSelectingUser: Boolean
get() = INTENT_ACTION_SELECT_USER == intent.action
private fun searchUser(name: String) {
val task = SearchUsersTask(this, accountKey, name)
AsyncTaskUtils.executeTask(task)
}
private fun setUserListsData(data: List<ParcelableUserList>, isMyAccount: Boolean) {
userListsAdapter.setData(data, true)
usersListContainer.visibility = View.GONE
userListsContainer.visibility = View.VISIBLE
createListContainer.visibility = if (isMyAccount) View.VISIBLE else View.GONE
}
@ -215,23 +159,26 @@ class UserListSelectorActivity : BaseActivity(), OnClickListener, OnItemClickLis
super.onStop()
}
private class GetUserListsTask internal constructor(private val mActivity: UserListSelectorActivity, private val mAccountKey: UserKey,
private val mScreenName: String) : AsyncTask<Any, Any, SingleResponse<List<ParcelableUserList>>>() {
private class GetUserListsTask(
private val activity: UserListSelectorActivity,
private val accountKey: UserKey,
private val screenName: String
) : AsyncTask<Any, Any, SingleResponse<List<ParcelableUserList>>>() {
override fun doInBackground(vararg params: Any): SingleResponse<List<ParcelableUserList>> {
val twitter = MicroBlogAPIFactory.getInstance(mActivity, mAccountKey) ?: return SingleResponse.getInstance<List<ParcelableUserList>>()
val twitter = MicroBlogAPIFactory.getInstance(activity, accountKey) ?: return SingleResponse.getInstance<List<ParcelableUserList>>()
try {
val lists = twitter.getUserListsByScreenName(mScreenName, true)
val lists = twitter.getUserListsByScreenName(screenName, true)
val data = ArrayList<ParcelableUserList>()
var isMyAccount = mScreenName.equals(getAccountScreenName(mActivity,
mAccountKey), ignoreCase = true)
var isMyAccount = screenName.equals(getAccountScreenName(activity,
accountKey), ignoreCase = true)
for (item in lists) {
val user = item.user
if (user != null && mScreenName.equals(user.screenName, ignoreCase = true)) {
if (!isMyAccount && TextUtils.equals(user.id, mAccountKey.id)) {
if (user != null && screenName.equals(user.screenName, ignoreCase = true)) {
if (!isMyAccount && TextUtils.equals(user.id, accountKey.id)) {
isMyAccount = true
}
data.add(ParcelableUserListUtils.from(item, mAccountKey))
data.add(ParcelableUserListUtils.from(item, accountKey))
}
}
val result = SingleResponse.getInstance<List<ParcelableUserList>>(data)
@ -245,12 +192,12 @@ class UserListSelectorActivity : BaseActivity(), OnClickListener, OnItemClickLis
}
override fun onPostExecute(result: SingleResponse<List<ParcelableUserList>>) {
mActivity.dismissDialogFragment(FRAGMENT_TAG_GET_USER_LISTS)
activity.dismissDialogFragment(FRAGMENT_TAG_GET_USER_LISTS)
if (result.data != null) {
mActivity.setUserListsData(result.data, result.extras.getBoolean(EXTRA_IS_MY_ACCOUNT))
activity.setUserListsData(result.data, result.extras.getBoolean(EXTRA_IS_MY_ACCOUNT))
} else if (result.exception is MicroBlogException) {
if (result.exception.statusCode == HttpResponseCode.NOT_FOUND) {
mActivity.searchUser(mScreenName)
// activity.searchUser(screenName)
}
}
}
@ -258,7 +205,7 @@ class UserListSelectorActivity : BaseActivity(), OnClickListener, OnItemClickLis
override fun onPreExecute() {
val df = ProgressDialogFragment()
df.isCancelable = false
mActivity.showDialogFragment(df, FRAGMENT_TAG_GET_USER_LISTS)
activity.showDialogFragment(df, FRAGMENT_TAG_GET_USER_LISTS)
}
companion object {
@ -268,45 +215,5 @@ class UserListSelectorActivity : BaseActivity(), OnClickListener, OnItemClickLis
}
private class SearchUsersTask internal constructor(private val activity: UserListSelectorActivity, private val mAccountKey: UserKey,
private val mName: String) : AsyncTask<Any, Any, SingleResponse<List<ParcelableUser>>>() {
override fun doInBackground(vararg params: Any): SingleResponse<List<ParcelableUser>> {
val twitter = MicroBlogAPIFactory.getInstance(activity, mAccountKey) ?: return SingleResponse.getInstance<List<ParcelableUser>>()
try {
val paging = Paging()
val lists = twitter.searchUsers(mName, paging)
val data = ArrayList<ParcelableUser>()
for (item in lists) {
data.add(ParcelableUserUtils.fromUser(item, mAccountKey))
}
return SingleResponse.getInstance<List<ParcelableUser>>(data)
} catch (e: MicroBlogException) {
Log.w(LOGTAG, e)
return SingleResponse.getInstance<List<ParcelableUser>>(e)
}
}
override fun onPostExecute(result: SingleResponse<List<ParcelableUser>>) {
activity.dismissDialogFragment(FRAGMENT_TAG_SEARCH_USERS)
if (result.data != null) {
activity.setUsersData(result.data)
}
}
override fun onPreExecute() {
val df = ProgressDialogFragment()
df.isCancelable = false
activity.showDialogFragment(df, FRAGMENT_TAG_SEARCH_USERS)
}
companion object {
private const val FRAGMENT_TAG_SEARCH_USERS = "search_users"
}
}
}

View File

@ -0,0 +1,202 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity
import android.app.Activity
import android.content.Intent
import android.os.AsyncTask
import android.os.Bundle
import android.support.v4.app.DialogFragment
import android.text.TextUtils.isEmpty
import android.util.Log
import android.view.View
import android.view.View.OnClickListener
import android.widget.AdapterView
import android.widget.AdapterView.OnItemClickListener
import android.widget.ListView
import kotlinx.android.synthetic.main.activity_user_selector.*
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter
import org.mariotaku.twidere.adapter.UserAutoCompleteAdapter
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.fragment.CreateUserListDialogFragment
import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.SingleResponse
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.ParcelableUserUtils
import org.mariotaku.twidere.util.AsyncTaskUtils
import org.mariotaku.twidere.util.MicroBlogAPIFactory
import org.mariotaku.twidere.util.ParseUtils
import java.util.*
class UserSelectorActivity : BaseActivity(), OnClickListener, OnItemClickListener {
private lateinit var usersAdapter: SimpleParcelableUsersAdapter
private var screenName: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intent = intent
if (!intent.hasExtra(EXTRA_ACCOUNT_KEY)) {
finish()
return
}
setContentView(R.layout.activity_user_selector)
if (savedInstanceState == null) {
screenName = intent.getStringExtra(EXTRA_SCREEN_NAME)
} else {
screenName = savedInstanceState.getString(EXTRA_SCREEN_NAME)
}
if (!isEmpty(screenName)) {
searchUser(screenName!!)
}
val adapter = UserAutoCompleteAdapter(this)
adapter.accountKey = accountKey
editScreenName.setAdapter(adapter)
editScreenName.setText(screenName)
usersAdapter = SimpleParcelableUsersAdapter(this)
usersList.adapter = usersAdapter
usersList.onItemClickListener = this
screenNameConfirm.setOnClickListener(this)
}
override fun onClick(v: View) {
when (v.id) {
R.id.screenNameConfirm -> {
val screen_name = ParseUtils.parseString(editScreenName.text)
if (isEmpty(screen_name)) return
searchUser(screen_name)
}
R.id.createList -> {
val f = CreateUserListDialogFragment()
val args = Bundle()
args.putParcelable(EXTRA_ACCOUNT_KEY, accountKey)
f.arguments = args
f.show(supportFragmentManager, null)
}
}
}
override fun onItemClick(view: AdapterView<*>, child: View, position: Int, id: Long) {
val list = view as ListView
val user = usersAdapter.getItem(position - list.headerViewsCount) ?: return
val data = Intent()
data.setExtrasClassLoader(classLoader)
data.putExtra(EXTRA_USER, user)
setResult(Activity.RESULT_OK, data)
finish()
}
fun setUsersData(data: List<ParcelableUser>) {
usersAdapter.setData(data, true)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString(EXTRA_SCREEN_NAME, screenName)
}
private val accountKey: UserKey
get() = intent.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY)
private fun searchUser(name: String) {
val task = SearchUsersTask(this, accountKey, name)
AsyncTaskUtils.executeTask(task)
}
private fun dismissDialogFragment(tag: String) {
executeAfterFragmentResumed { activity ->
val fm = activity.supportFragmentManager
val f = fm.findFragmentByTag(tag)
if (f is DialogFragment) {
f.dismiss()
}
}
}
private fun showDialogFragment(df: DialogFragment, tag: String) {
executeAfterFragmentResumed { activity ->
df.show(activity.supportFragmentManager, tag)
}
}
override fun onStart() {
super.onStart()
bus.register(this)
}
override fun onStop() {
bus.unregister(this)
super.onStop()
}
private class SearchUsersTask(
private val activity: UserSelectorActivity,
private val accountKey: UserKey,
private val name: String
) : AsyncTask<Any, Any, SingleResponse<List<ParcelableUser>>>() {
override fun doInBackground(vararg params: Any): SingleResponse<List<ParcelableUser>> {
val twitter = MicroBlogAPIFactory.getInstance(activity, accountKey) ?: return SingleResponse.getInstance<List<ParcelableUser>>()
try {
val paging = Paging()
val lists = twitter.searchUsers(name, paging)
val data = ArrayList<ParcelableUser>()
for (item in lists) {
data.add(ParcelableUserUtils.fromUser(item, accountKey))
}
return SingleResponse.getInstance<List<ParcelableUser>>(data)
} catch (e: MicroBlogException) {
Log.w(LOGTAG, e)
return SingleResponse.getInstance<List<ParcelableUser>>(e)
}
}
override fun onPostExecute(result: SingleResponse<List<ParcelableUser>>) {
activity.dismissDialogFragment(FRAGMENT_TAG_SEARCH_USERS)
if (result.data != null) {
activity.setUsersData(result.data)
}
}
override fun onPreExecute() {
val df = ProgressDialogFragment()
df.isCancelable = false
activity.showDialogFragment(df, FRAGMENT_TAG_SEARCH_USERS)
}
companion object {
private const val FRAGMENT_TAG_SEARCH_USERS = "search_users"
}
}
}

View File

@ -49,7 +49,7 @@ import org.mariotaku.microblog.library.twitter.model.UserListUpdate
import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.AccountSelectorActivity
import org.mariotaku.twidere.activity.UserListSelectorActivity
import org.mariotaku.twidere.activity.UserSelectorActivity
import org.mariotaku.twidere.adapter.SupportTabsAdapter
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
@ -213,7 +213,7 @@ class UserListFragment : AbsToolbarTabPagesFragment(), OnClickListener, LoaderCa
R.id.add -> {
if (userList.user_key != userList.account_key) return false
val intent = Intent(INTENT_ACTION_SELECT_USER)
intent.setClass(activity, UserListSelectorActivity::class.java)
intent.setClass(activity, UserSelectorActivity::class.java)
intent.putExtra(EXTRA_ACCOUNT_KEY, userList.account_key)
startActivityForResult(intent, REQUEST_SELECT_USER)
}

View File

@ -24,7 +24,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.AccountSelectorActivity
import org.mariotaku.twidere.activity.LinkHandlerActivity
import org.mariotaku.twidere.activity.UserListSelectorActivity
import org.mariotaku.twidere.activity.UserSelectorActivity
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_HOST
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
@ -81,7 +81,7 @@ class FilteredUsersFragment : BaseFiltersFragment() {
REQUEST_ADD_USER_SELECT_ACCOUNT -> {
if (resultCode != FragmentActivity.RESULT_OK) return
val intent = Intent(INTENT_ACTION_SELECT_USER)
intent.setClass(context, UserListSelectorActivity::class.java)
intent.setClass(context, UserSelectorActivity::class.java)
intent.putExtra(EXTRA_ACCOUNT_KEY, data!!.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY))
startActivityForResult(intent, REQUEST_ADD_USER_SELECT_ACCOUNT)
}

View File

@ -9,7 +9,7 @@ import android.view.ViewGroup
import kotlinx.android.synthetic.main.layout_extra_config_user.view.*
import kotlinx.android.synthetic.main.list_item_simple_user.view.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.UserListSelectorActivity
import org.mariotaku.twidere.activity.UserSelectorActivity
import org.mariotaku.twidere.adapter.DummyItemAdapter
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.fragment.CustomTabsFragment.TabEditorDialogFragment
@ -45,7 +45,7 @@ class UserExtraConfiguration(key: String) : TabConfiguration.ExtraConfiguration(
val account = fragment.account ?: return@setOnClickListener
val intent = Intent(INTENT_ACTION_SELECT_USER)
intent.putExtra(EXTRA_ACCOUNT_KEY, account.key)
intent.setClass(context, UserListSelectorActivity::class.java)
intent.setClass(context, UserSelectorActivity::class.java)
fragment.startExtraConfigurationActivityForResult(this@UserExtraConfiguration, intent, 1)
}
hintView = view.selectUserHint

View File

@ -58,59 +58,5 @@
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/usersListContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="?android:dividerVertical"
android:orientation="vertical"
android:showDividers="middle"
tools:context=".activity.UserListSelectorActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
style="?android:listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/title_user"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal">
<AutoCompleteTextView
android:id="@+id/editScreenName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:maxLines="1"/>
<org.mariotaku.twidere.view.IconActionButton
android:id="@+id/screenNameConfirm"
android:layout_width="@dimen/minimum_element_size"
android:layout_height="@dimen/minimum_element_size"
android:layout_weight="0"
android:background="?selectableItemBackground"
android:color="?menuIconColor"
android:contentDescription="@string/search"
android:src="@drawable/ic_action_search"
tools:tint="?menuIconColor"/>
</LinearLayout>
</LinearLayout>
<ListView
android:id="@+id/usersList"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</merge>

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.UserSelectorActivity">
<LinearLayout
android:id="@+id/usersListContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="?android:dividerVertical"
android:orientation="vertical"
android:showDividers="middle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
style="?android:listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/title_user"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal">
<AutoCompleteTextView
android:id="@+id/editScreenName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:maxLines="1"/>
<org.mariotaku.twidere.view.IconActionButton
android:id="@+id/screenNameConfirm"
android:layout_width="@dimen/minimum_element_size"
android:layout_height="@dimen/minimum_element_size"
android:layout_weight="0"
android:background="?selectableItemBackground"
android:color="?menuIconColor"
android:contentDescription="@string/search"
android:src="@drawable/ic_action_search"
tools:tint="?menuIconColor"/>
</LinearLayout>
</LinearLayout>
<ListView
android:id="@+id/usersList"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</merge>