rewrite custom tab part

This commit is contained in:
Mariotaku Lee 2016-12-01 10:16:55 +08:00
parent 5c0488d2cf
commit 4f32d67e79
29 changed files with 598 additions and 263 deletions

View File

@ -1,11 +1,12 @@
package org.mariotaku.twidere.model.tab;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.CallSuper;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
@ -16,6 +17,7 @@ import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.annotation.CustomTabType;
import org.mariotaku.twidere.fragment.CustomTabsFragment.TabEditorDialogFragment;
import org.mariotaku.twidere.model.Tab;
import org.mariotaku.twidere.model.tab.impl.DMTabConfiguration;
import org.mariotaku.twidere.model.tab.impl.FavoriteTimelineTabConfiguration;
@ -38,9 +40,10 @@ import kotlin.Pair;
public abstract class TabConfiguration {
public static final int FLAG_HAS_ACCOUNT = 0b001;
public static final int FLAG_ACCOUNT_REQUIRED = 0b010;
public static final int FLAG_ACCOUNT_MULTIPLE = 0b100;
public static final int FLAG_HAS_ACCOUNT = 0b0001;
public static final int FLAG_ACCOUNT_REQUIRED = 0b0010;
public static final int FLAG_ACCOUNT_MULTIPLE = 0b0100;
public static final int FLAG_ACCOUNT_MUTABLE = 0b1000;
@NonNull
public abstract StringHolder getName();
@ -48,8 +51,8 @@ public abstract class TabConfiguration {
@NonNull
public abstract DrawableHolder getIcon();
@AccountRequirement
public abstract int getAccountRequirement();
@AccountFlags
public abstract int getAccountFlags();
public boolean isSingleTab() {
return false;
@ -67,16 +70,17 @@ public abstract class TabConfiguration {
@NonNull
public abstract Class<? extends Fragment> getFragmentClass();
public void applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
public boolean applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
return true;
}
public void readExtraConfigurationFrom(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
public boolean readExtraConfigurationFrom(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
return false;
}
@IntDef(value = {FLAG_HAS_ACCOUNT, FLAG_ACCOUNT_REQUIRED, FLAG_ACCOUNT_MULTIPLE}, flag = true)
protected @interface AccountRequirement {
@IntDef(value = {FLAG_HAS_ACCOUNT, FLAG_ACCOUNT_REQUIRED, FLAG_ACCOUNT_MULTIPLE,
FLAG_ACCOUNT_MUTABLE}, flag = true)
protected @interface AccountFlags {
}
@ -133,6 +137,9 @@ public abstract class TabConfiguration {
private StringHolder title;
@Nullable
private StringHolder headerTitle;
private int position;
private boolean mutable;
private Context context;
protected ExtraConfiguration(String key) {
this.key = key;
@ -179,10 +186,44 @@ public abstract class TabConfiguration {
return this;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public boolean isMutable() {
return mutable;
}
public void setMutable(boolean mutable) {
this.mutable = mutable;
}
public ExtraConfiguration mutable(boolean mutable) {
setMutable(mutable);
return this;
}
@NonNull
public abstract View onCreateView(Context context, ViewGroup parent);
public void onViewCreated(@NonNull Context context, @NonNull View view, @NonNull DialogFragment fragment) {
@CallSuper
public void onCreate(Context context) {
this.context = context;
}
public final Context getContext() {
return context;
}
public void onViewCreated(@NonNull Context context, @NonNull View view, @NonNull TabEditorDialogFragment fragment) {
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}
@ -200,11 +241,11 @@ public abstract class TabConfiguration {
@NonNull
@Override
public View onCreateView(Context context, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.list_item_extra_config, parent, false);
return LayoutInflater.from(context).inflate(R.layout.layout_extra_config_checkbox, parent, false);
}
@Override
public void onViewCreated(@NonNull Context context, @NonNull View view, @NonNull DialogFragment fragment) {
public void onViewCreated(@NonNull Context context, @NonNull View view, @NonNull TabEditorDialogFragment fragment) {
final TextView titleView = (TextView) view.findViewById(android.R.id.title);
titleView.setText(getTitle().createString(context));
@ -247,7 +288,7 @@ public abstract class TabConfiguration {
}
@Override
public void onViewCreated(@NonNull Context context, @NonNull View view, @NonNull DialogFragment fragment) {
public void onViewCreated(@NonNull Context context, @NonNull View view, @NonNull final TabEditorDialogFragment fragment) {
editText = (EditText) view.findViewById(R.id.editText);
editText.setHint(getTitle().createString(context));
editText.setText(def);

View File

@ -1,44 +0,0 @@
package org.mariotaku.twidere.model.tab.conf;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.UserListSelectorActivity;
import org.mariotaku.twidere.model.tab.TabConfiguration;
import static org.mariotaku.twidere.constant.IntentConstants.INTENT_ACTION_SELECT_USER;
/**
* Created by mariotaku on 2016/11/28.
*/
public class UserExtraConfiguration extends TabConfiguration.ExtraConfiguration {
public UserExtraConfiguration(String key) {
super(key);
}
@NonNull
@Override
public View onCreateView(Context context, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.list_item_simple_user, parent, false);
}
@Override
public void onViewCreated(@NonNull final Context context, @NonNull View view, @NonNull final DialogFragment fragment) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER);
intent.setClass(context, UserListSelectorActivity.class);
fragment.startActivity(intent);
}
});
}
}

View File

@ -1,45 +0,0 @@
package org.mariotaku.twidere.model.tab.conf;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.UserListSelectorActivity;
import org.mariotaku.twidere.model.tab.TabConfiguration;
import static org.mariotaku.twidere.constant.IntentConstants.INTENT_ACTION_SELECT_USER;
import static org.mariotaku.twidere.constant.IntentConstants.INTENT_ACTION_SELECT_USER_LIST;
/**
* Created by mariotaku on 2016/11/28.
*/
public class UserListExtraConfiguration extends TabConfiguration.ExtraConfiguration {
public UserListExtraConfiguration(String key) {
super(key);
}
@NonNull
@Override
public View onCreateView(Context context, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.list_item_simple_user_list, parent, false);
}
@Override
public void onViewCreated(@NonNull final Context context, @NonNull final View view, @NonNull final DialogFragment fragment) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final Intent intent = new Intent(INTENT_ACTION_SELECT_USER_LIST);
intent.setClass(context, UserListSelectorActivity.class);
fragment.startActivity(intent);
}
});
}
}

View File

@ -0,0 +1,12 @@
package org.mariotaku.twidere.model.tab.iface;
import org.mariotaku.twidere.model.ParcelableAccount;
/**
* Created by mariotaku on 2016/11/30.
*/
public interface AccountCallback {
ParcelableAccount getAccount();
}

View File

@ -5,9 +5,9 @@ import android.support.v4.app.Fragment;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.MessagesEntriesFragment;
import org.mariotaku.twidere.model.tab.TabConfiguration;
import org.mariotaku.twidere.model.tab.DrawableHolder;
import org.mariotaku.twidere.model.tab.StringHolder;
import org.mariotaku.twidere.model.tab.TabConfiguration;
/**
* Created by mariotaku on 2016/11/27.
@ -26,10 +26,10 @@ public class DMTabConfiguration extends TabConfiguration {
return DrawableHolder.Builtin.MESSAGE;
}
@AccountRequirement
@AccountFlags
@Override
public int getAccountRequirement() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_MULTIPLE;
public int getAccountFlags() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_MULTIPLE | FLAG_ACCOUNT_MUTABLE;
}
@NonNull

View File

@ -7,9 +7,12 @@ import android.support.v4.app.Fragment;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.UserFavoritesFragment;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.Tab;
import org.mariotaku.twidere.model.tab.DrawableHolder;
import org.mariotaku.twidere.model.tab.StringHolder;
import org.mariotaku.twidere.model.tab.TabConfiguration;
import org.mariotaku.twidere.model.tab.argument.UserArguments;
import org.mariotaku.twidere.model.tab.conf.UserExtraConfiguration;
import static org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER;
@ -31,9 +34,9 @@ public class FavoriteTimelineTabConfiguration extends TabConfiguration {
return DrawableHolder.Builtin.FAVORITE;
}
@AccountRequirement
@AccountFlags
@Override
public int getAccountRequirement() {
public int getAccountFlags() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_REQUIRED;
}
@ -45,6 +48,21 @@ public class FavoriteTimelineTabConfiguration extends TabConfiguration {
};
}
@Override
public boolean applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
UserArguments arguments = (UserArguments) tab.getArguments();
assert arguments != null;
switch (extraConf.getKey()) {
case EXTRA_USER: {
final ParcelableUser user = ((UserExtraConfiguration) extraConf).getValue();
if (user == null) return false;
arguments.setUserKey(user.key);
break;
}
}
return true;
}
@NonNull
@Override
public Class<? extends Fragment> getFragmentClass() {

View File

@ -34,24 +34,24 @@ public class HomeTabConfiguration extends TabConfiguration {
return DrawableHolder.Builtin.HOME;
}
@AccountRequirement
@AccountFlags
@Override
public int getAccountRequirement() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_MULTIPLE;
public int getAccountFlags() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_MULTIPLE | FLAG_ACCOUNT_MUTABLE;
}
@Nullable
@Override
public ExtraConfiguration[] getExtraConfigurations(Context context) {
return new ExtraConfiguration[]{
new BooleanExtraConfiguration(EXTRA_HIDE_RETWEETS, false).title(R.string.hide_retweets),
new BooleanExtraConfiguration(EXTRA_HIDE_QUOTES, false).title(R.string.hide_quotes),
new BooleanExtraConfiguration(EXTRA_HIDE_REPLIES, false).title(R.string.hide_replies),
new BooleanExtraConfiguration(EXTRA_HIDE_RETWEETS, false).title(R.string.hide_retweets).mutable(true),
new BooleanExtraConfiguration(EXTRA_HIDE_QUOTES, false).title(R.string.hide_quotes).mutable(true),
new BooleanExtraConfiguration(EXTRA_HIDE_REPLIES, false).title(R.string.hide_replies).mutable(true),
};
}
@Override
public void applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
public boolean applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
final HomeTabExtras extras = (HomeTabExtras) tab.getExtras();
assert extras != null;
switch (extraConf.getKey()) {
@ -68,12 +68,13 @@ public class HomeTabConfiguration extends TabConfiguration {
break;
}
}
return true;
}
@Override
public void readExtraConfigurationFrom(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
public boolean readExtraConfigurationFrom(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
final HomeTabExtras extras = (HomeTabExtras) tab.getExtras();
if (extras == null) return;
if (extras == null) return false;
switch (extraConf.getKey()) {
case EXTRA_HIDE_RETWEETS: {
((BooleanExtraConfiguration) extraConf).setValue(extras.isHideRetweets());
@ -88,6 +89,7 @@ public class HomeTabConfiguration extends TabConfiguration {
break;
}
}
return true;
}
@NonNull

View File

@ -33,23 +33,23 @@ public class InteractionsTabConfiguration extends TabConfiguration {
return DrawableHolder.Builtin.NOTIFICATIONS;
}
@AccountRequirement
@AccountFlags
@Override
public int getAccountRequirement() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_MULTIPLE;
public int getAccountFlags() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_MULTIPLE | FLAG_ACCOUNT_MUTABLE;
}
@Nullable
@Override
public ExtraConfiguration[] getExtraConfigurations(Context context) {
return new ExtraConfiguration[]{
new BooleanExtraConfiguration(EXTRA_MY_FOLLOWING_ONLY, false).title(R.string.following_only),
new BooleanExtraConfiguration(EXTRA_MENTIONS_ONLY, false).title(R.string.mentions_only),
new BooleanExtraConfiguration(EXTRA_MY_FOLLOWING_ONLY, false).title(R.string.following_only).mutable(true),
new BooleanExtraConfiguration(EXTRA_MENTIONS_ONLY, false).title(R.string.mentions_only).mutable(true),
};
}
@Override
public void applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
public boolean applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
final InteractionsTabExtras extras = (InteractionsTabExtras) tab.getExtras();
assert extras != null;
switch (extraConf.getKey()) {
@ -62,12 +62,13 @@ public class InteractionsTabConfiguration extends TabConfiguration {
break;
}
}
return true;
}
@Override
public void readExtraConfigurationFrom(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
public boolean readExtraConfigurationFrom(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
final InteractionsTabExtras extras = (InteractionsTabExtras) tab.getExtras();
if (extras == null) return;
if (extras == null) return false;
switch (extraConf.getKey()) {
case EXTRA_MY_FOLLOWING_ONLY: {
((BooleanExtraConfiguration) extraConf).setValue(extras.isMyFollowingOnly());
@ -78,6 +79,7 @@ public class InteractionsTabConfiguration extends TabConfiguration {
break;
}
}
return true;
}
@NonNull

View File

@ -5,9 +5,9 @@ import android.support.v4.app.Fragment;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.DirectMessagesFragment;
import org.mariotaku.twidere.model.tab.TabConfiguration;
import org.mariotaku.twidere.model.tab.DrawableHolder;
import org.mariotaku.twidere.model.tab.StringHolder;
import org.mariotaku.twidere.model.tab.TabConfiguration;
/**
* Created by mariotaku on 2016/11/27.
@ -26,10 +26,10 @@ public class MessagesTabConfiguration extends TabConfiguration {
return DrawableHolder.Builtin.MESSAGE;
}
@AccountRequirement
@AccountFlags
@Override
public int getAccountRequirement() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_MULTIPLE;
public int getAccountFlags() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_MULTIPLE | FLAG_ACCOUNT_MUTABLE;
}
@NonNull

View File

@ -6,7 +6,7 @@ import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.TrendsSuggestionsFragment;
import org.mariotaku.twidere.fragment.StatusesSearchFragment;
import org.mariotaku.twidere.model.Tab;
import org.mariotaku.twidere.model.tab.DrawableHolder;
import org.mariotaku.twidere.model.tab.StringHolder;
@ -32,9 +32,9 @@ public class SearchTabConfiguration extends TabConfiguration {
return DrawableHolder.Builtin.SEARCH;
}
@AccountRequirement
@AccountFlags
@Override
public int getAccountRequirement() {
public int getAccountFlags() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_REQUIRED;
}
@ -47,32 +47,36 @@ public class SearchTabConfiguration extends TabConfiguration {
}
@Override
public void applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
public boolean applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
final TextQueryArguments arguments = (TextQueryArguments) tab.getArguments();
assert arguments != null;
switch (extraConf.getKey()) {
case EXTRA_QUERY: {
arguments.setQuery(((StringExtraConfiguration) extraConf).getValue());
final String query = ((StringExtraConfiguration) extraConf).getValue();
if (query == null) return false;
arguments.setQuery(query);
break;
}
}
return true;
}
@Override
public void readExtraConfigurationFrom(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
public boolean readExtraConfigurationFrom(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
final TextQueryArguments arguments = (TextQueryArguments) tab.getArguments();
if (arguments == null) return;
if (arguments == null) return false;
switch (extraConf.getKey()) {
case EXTRA_QUERY: {
((StringExtraConfiguration) extraConf).setValue(arguments.getQuery());
break;
}
}
return true;
}
@NonNull
@Override
public Class<? extends Fragment> getFragmentClass() {
return TrendsSuggestionsFragment.class;
return StatusesSearchFragment.class;
}
}

View File

@ -26,9 +26,9 @@ public class TrendsTabConfiguration extends TabConfiguration {
return DrawableHolder.Builtin.TRENDS;
}
@AccountRequirement
@AccountFlags
@Override
public int getAccountRequirement() {
public int getAccountFlags() {
return FLAG_HAS_ACCOUNT;
}

View File

@ -7,9 +7,12 @@ import android.support.v4.app.Fragment;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.UserListTimelineFragment;
import org.mariotaku.twidere.model.tab.TabConfiguration;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.model.Tab;
import org.mariotaku.twidere.model.tab.DrawableHolder;
import org.mariotaku.twidere.model.tab.StringHolder;
import org.mariotaku.twidere.model.tab.TabConfiguration;
import org.mariotaku.twidere.model.tab.argument.UserListArguments;
import org.mariotaku.twidere.model.tab.conf.UserListExtraConfiguration;
import static org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER_LIST;
@ -31,9 +34,9 @@ public class UserListTimelineTabConfiguration extends TabConfiguration {
return DrawableHolder.Builtin.LIST;
}
@AccountRequirement
@AccountFlags
@Override
public int getAccountRequirement() {
public int getAccountFlags() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_REQUIRED;
}
@ -45,6 +48,21 @@ public class UserListTimelineTabConfiguration extends TabConfiguration {
};
}
@Override
public boolean applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
UserListArguments arguments = (UserListArguments) tab.getArguments();
assert arguments != null;
switch (extraConf.getKey()) {
case EXTRA_USER_LIST: {
final ParcelableUserList userList = ((UserListExtraConfiguration) extraConf).getValue();
if (userList == null) return false;
arguments.setListId(userList.id);
break;
}
}
return true;
}
@NonNull
@Override
public Class<? extends Fragment> getFragmentClass() {

View File

@ -7,9 +7,12 @@ import android.support.v4.app.Fragment;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.UserTimelineFragment;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.Tab;
import org.mariotaku.twidere.model.tab.DrawableHolder;
import org.mariotaku.twidere.model.tab.StringHolder;
import org.mariotaku.twidere.model.tab.TabConfiguration;
import org.mariotaku.twidere.model.tab.argument.UserArguments;
import org.mariotaku.twidere.model.tab.conf.UserExtraConfiguration;
import static org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER;
@ -31,9 +34,9 @@ public class UserTimelineTabConfiguration extends TabConfiguration {
return DrawableHolder.Builtin.USER;
}
@AccountRequirement
@AccountFlags
@Override
public int getAccountRequirement() {
public int getAccountFlags() {
return FLAG_HAS_ACCOUNT | FLAG_ACCOUNT_REQUIRED;
}
@ -45,6 +48,21 @@ public class UserTimelineTabConfiguration extends TabConfiguration {
};
}
@Override
public boolean applyExtraConfigurationTo(@NonNull Tab tab, @NonNull ExtraConfiguration extraConf) {
UserArguments arguments = (UserArguments) tab.getArguments();
assert arguments != null;
switch (extraConf.getKey()) {
case EXTRA_USER: {
final ParcelableUser user = ((UserExtraConfiguration) extraConf).getValue();
if (user == null) return false;
arguments.setUserKey(user.key);
break;
}
}
return true;
}
@NonNull
@Override
public Class<? extends Fragment> getFragmentClass() {

View File

@ -35,6 +35,7 @@ import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.model.util.ParcelableUserUtils;
import org.mariotaku.twidere.util.imageloader.OvalBitmapDisplayer;
@ -176,6 +177,10 @@ public class MediaLoaderWrapper {
}
}
public void displayProfileImage(final ImageView view, final ParcelableUserList userList) {
displayProfileImage(view, userList.user_profile_image_url);
}
public void displayProfileImage(final ImageView view, final ParcelableAccount account) {
if (account.account_user != null && account.account_user.extras != null
&& !TextUtils.isEmpty(account.account_user.extras.profile_image_url_profile_size)) {

View File

@ -4,12 +4,13 @@ import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.TextView;
import com.afollestad.appthemeengine.Config;
import com.afollestad.appthemeengine.viewprocessors.ViewProcessor;
import org.mariotaku.twidere.util.view.SimpleTextWatcher;
import static org.mariotaku.twidere.constant.SharedPreferenceConstants.VALUE_THEME_NAME_DARK;
/**
@ -52,21 +53,4 @@ public class TextViewViewProcessor implements ViewProcessor<TextView, Void> {
}
}
abstract static class SimpleTextWatcher implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
}
}
}

View File

@ -0,0 +1,25 @@
package org.mariotaku.twidere.util.view;
import android.text.Editable;
import android.text.TextWatcher;
/**
* Created by mariotaku on 2016/11/30.
*/
public abstract class SimpleTextWatcher implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
}
}

View File

@ -62,6 +62,12 @@ class DependencyHolder internal constructor(context: Context) {
@Inject
lateinit var defaultFeatures: DefaultFeatures
internal set
@Inject
lateinit var mediaLoader: MediaLoaderWrapper
internal set
@Inject
lateinit var userColorNameManager: UserColorNameManager
internal set
init {
GeneralComponentHelper.build(context).inject(this)

View File

@ -27,7 +27,7 @@ import org.mariotaku.twidere.adapter.iface.IBaseAdapter
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.Utils.configBaseAdapter
import org.mariotaku.twidere.util.Utils.getUserTypeIconRes
import org.mariotaku.twidere.util.display
import org.mariotaku.twidere.view.holder.TwoLineWithIconViewHolder
class SimpleParcelableUsersAdapter @JvmOverloads constructor(
@ -61,16 +61,7 @@ class SimpleParcelableUsersAdapter @JvmOverloads constructor(
val user = getItem(position)
holder.text1.setCompoundDrawablesWithIntrinsicBounds(0, 0,
getUserTypeIconRes(user.is_verified, user.is_protected), 0)
holder.text1.text = userColorNameManager.getUserNickname(user.key, user.name)
holder.text2.text = String.format("@%s", user.screen_name)
holder.icon.visibility = if (isProfileImageDisplayed) View.VISIBLE else View.GONE
if (isProfileImageDisplayed) {
mediaLoader.displayProfileImage(holder.icon, user)
} else {
mediaLoader.cancelDisplayTask(holder.icon)
}
holder.display(user, mediaLoader, userColorNameManager, isProfileImageDisplayed)
return view
}

View File

@ -34,6 +34,7 @@ import android.support.v4.content.CursorLoader
import android.support.v4.content.Loader
import android.support.v7.app.AlertDialog
import android.text.TextUtils
import android.util.SparseArray
import android.view.*
import android.widget.*
import android.widget.AbsListView.MultiChoiceModeListener
@ -60,6 +61,7 @@ import org.mariotaku.twidere.model.TabCursorIndices
import org.mariotaku.twidere.model.TabValuesCreator
import org.mariotaku.twidere.model.tab.DrawableHolder
import org.mariotaku.twidere.model.tab.TabConfiguration
import org.mariotaku.twidere.model.tab.iface.AccountCallback
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs
import org.mariotaku.twidere.util.CustomTabUtils
import org.mariotaku.twidere.util.DataStoreUtils
@ -165,7 +167,7 @@ class CustomTabsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, Mult
val subMenu = itemAdd.subMenu
subMenu.clear()
for ((type, conf) in TabConfiguration.all()) {
val accountIdRequired = (conf.accountRequirement and TabConfiguration.FLAG_ACCOUNT_REQUIRED) != 0
val accountIdRequired = (conf.accountFlags and TabConfiguration.FLAG_ACCOUNT_REQUIRED) != 0
val subItem = subMenu.add(0, 0, conf.sortPosition, conf.name.createString(context))
val disabledByNoAccount = accountIdRequired && accountIds.isEmpty()
val disabledByDuplicateTab = conf.isSingleTab && CustomTabUtils.isTabAdded(context, type)
@ -259,16 +261,12 @@ class CustomTabsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, Mult
mode.title = resources.getQuantityString(R.plurals.Nitems_selected, count, count)
}
class TabEditorDialogFragment : BaseDialogFragment() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
}
class TabEditorDialogFragment : BaseDialogFragment(), DialogInterface.OnShowListener, AccountCallback {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context)
builder.setView(R.layout.dialog_custom_tab_editor)
builder.setPositiveButton(R.string.save, null)
builder.setNegativeButton(android.R.string.cancel, null)
private val activityResultMap: SparseArray<TabConfiguration.ExtraConfiguration> = SparseArray()
override fun onShow(dialog: DialogInterface) {
dialog as AlertDialog
@CustomTabType
val tabType: String
val tab: Tab
@ -292,89 +290,133 @@ class CustomTabsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, Mult
}
}
val dialog = builder.create()
dialog.setOnShowListener {
val tabName = dialog.findViewById(R.id.tabName) as EditText
val iconSpinner = dialog.findViewById(R.id.tab_icon_spinner) as Spinner
val accountSpinner = dialog.findViewById(R.id.account_spinner) as Spinner
val accountContainer = dialog.findViewById(R.id.account_container)!!
val accountSectionHeader = accountContainer.sectionHeader
val extraConfigContainer = dialog.findViewById(R.id.extra_config_container) as LinearLayout
val tabName = dialog.findViewById(R.id.tabName) as EditText
val iconSpinner = dialog.findViewById(R.id.tab_icon_spinner) as Spinner
val accountSpinner = dialog.findViewById(R.id.account_spinner) as Spinner
val accountContainer = dialog.findViewById(R.id.account_container)!!
val accountSectionHeader = accountContainer.sectionHeader
val extraConfigContainer = dialog.findViewById(R.id.extra_config_container) as LinearLayout
val positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE)
val positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE)
val iconsAdapter = TabIconsAdapter(context)
val accountsAdapter = AccountsSpinnerAdapter(context)
iconSpinner.adapter = iconsAdapter
accountSpinner.adapter = accountsAdapter
val iconsAdapter = TabIconsAdapter(context)
val accountsAdapter = AccountsSpinnerAdapter(context)
iconSpinner.adapter = iconsAdapter
accountSpinner.adapter = accountsAdapter
iconsAdapter.setData(DrawableHolder.builtins())
iconsAdapter.setData(DrawableHolder.builtins())
tabName.setText(tab.name ?: conf.name.createString(context))
iconSpinner.setSelection(iconsAdapter.findPositionByKey(tab.icon))
accountSectionHeader.setText(R.string.account)
tabName.hint = conf.name.createString(context)
tabName.setText(tab.name)
iconSpinner.setSelection(iconsAdapter.findPositionByKey(tab.icon))
accountSectionHeader.setText(R.string.account)
val hasAccount = conf.accountRequirement and TabConfiguration.FLAG_HAS_ACCOUNT != 0
if (hasAccount) {
accountContainer.visibility = View.VISIBLE
val accountIdRequired = conf.accountRequirement and TabConfiguration.FLAG_ACCOUNT_REQUIRED != 0
accountsAdapter.clear()
if (!accountIdRequired) {
accountsAdapter.add(ParcelableAccount.dummyCredentials())
}
val officialKeyOnly = arguments.getBoolean(EXTRA_OFFICIAL_KEY_ONLY, false)
accountsAdapter.addAll(DataStoreUtils.getCredentialsList(context, false, officialKeyOnly))
accountsAdapter.setDummyItemText(R.string.activated_accounts)
val editMode = tag == TAG_EDIT_TAB
tab.arguments?.accountKeys?.firstOrNull()?.let { key ->
accountSpinner.setSelection(accountsAdapter.findPositionByKey(key))
}
} else {
accountContainer.visibility = View.GONE
val hasAccount = conf.accountFlags and TabConfiguration.FLAG_HAS_ACCOUNT != 0
val accountMutable = conf.accountFlags and TabConfiguration.FLAG_ACCOUNT_MUTABLE != 0
if (hasAccount && (accountMutable || !editMode)) {
accountContainer.visibility = View.VISIBLE
val accountIdRequired = conf.accountFlags and TabConfiguration.FLAG_ACCOUNT_REQUIRED != 0
accountsAdapter.clear()
if (!accountIdRequired) {
accountsAdapter.add(ParcelableAccount.dummyCredentials())
}
val officialKeyOnly = arguments.getBoolean(EXTRA_OFFICIAL_KEY_ONLY, false)
accountsAdapter.addAll(DataStoreUtils.getCredentialsList(context, false, officialKeyOnly))
accountsAdapter.setDummyItemText(R.string.activated_accounts)
val extraConfigurations = conf.getExtraConfigurations(context).orEmpty()
fun inflateHeader(title: String): View {
val headerView = LayoutInflater.from(context).inflate(R.layout.list_item_section_header,
extraConfigContainer, false)
headerView.sectionHeader.text = title
return headerView
}
extraConfigurations.forEachIndexed { idx, extraConf ->
extraConf.headerTitle?.let {
extraConfigContainer.addView(inflateHeader(it.createString(context)))
}
val view = extraConf.onCreateView(context, extraConfigContainer)
extraConf.onViewCreated(context, view, this)
conf.readExtraConfigurationFrom(tab, extraConf)
extraConfigContainer.addView(view)
}
positiveButton.setOnClickListener {
tab.name = tabName.text.toString()
tab.icon = (iconSpinner.selectedItem as DrawableHolder).persistentKey
tab.arguments = CustomTabUtils.newTabArguments(tabType)
if (hasAccount) {
val account = accountSpinner.selectedItem as ParcelableAccount
if (!account.is_dummy) {
tab.arguments?.accountKeys = arrayOf(account.account_key)
} else {
tab.arguments?.accountKeys = null
}
}
tab.extras = CustomTabUtils.newTabExtras(tabType)
extraConfigurations.forEach {
conf.applyExtraConfigurationTo(tab, it)
}
context.contentResolver.insert(Tabs.CONTENT_URI, TabValuesCreator.create(tab))
dismiss()
tab.arguments?.accountKeys?.firstOrNull()?.let { key ->
accountSpinner.setSelection(accountsAdapter.findPositionByKey(key))
}
} else {
accountContainer.visibility = View.GONE
}
val extraConfigurations = conf.getExtraConfigurations(context).orEmpty()
fun inflateHeader(title: String): View {
val headerView = LayoutInflater.from(context).inflate(R.layout.list_item_section_header,
extraConfigContainer, false)
headerView.sectionHeader.text = title
return headerView
}
extraConfigurations.forEachIndexed { idx, extraConf ->
extraConf.onCreate(context)
extraConf.position = idx + 1
// Hide immutable settings in edit mode
if (editMode && !extraConf.isMutable) return@forEachIndexed
extraConf.headerTitle?.let {
// Inflate header with headerTitle
extraConfigContainer.addView(inflateHeader(it.createString(context)))
}
val view = extraConf.onCreateView(context, extraConfigContainer)
extraConf.onViewCreated(context, view, this)
conf.readExtraConfigurationFrom(tab, extraConf)
extraConfigContainer.addView(view)
}
positiveButton.setOnClickListener {
tab.name = tabName.text.toString()
tab.icon = (iconSpinner.selectedItem as DrawableHolder).persistentKey
tab.arguments = CustomTabUtils.newTabArguments(tabType)
if (hasAccount) {
val account = accountSpinner.selectedItem as ParcelableAccount
if (!account.is_dummy) {
tab.arguments?.accountKeys = arrayOf(account.account_key)
} else {
tab.arguments?.accountKeys = null
}
}
tab.extras = CustomTabUtils.newTabExtras(tabType)
extraConfigurations.forEach {
// Make sure immutable configuration skipped in edit mode
if (editMode && !it.isMutable) return@forEach
if (!conf.applyExtraConfigurationTo(tab, it)) {
return@setOnClickListener
}
}
when (tag) {
TAG_EDIT_TAB -> {
val where = Expression.equalsArgs(Tabs._ID).sql
val whereArgs = arrayOf(tab.id.toString())
context.contentResolver.update(Tabs.CONTENT_URI, TabValuesCreator.create(tab), where, whereArgs)
}
TAG_ADD_TAB -> {
context.contentResolver.insert(Tabs.CONTENT_URI, TabValuesCreator.create(tab))
}
}
dismiss()
}
}
override fun getAccount(): ParcelableAccount {
return (dialog.findViewById(R.id.account_spinner) as Spinner).selectedItem as ParcelableAccount
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context)
builder.setView(R.layout.dialog_custom_tab_editor)
builder.setPositiveButton(R.string.save, null)
builder.setNegativeButton(android.R.string.cancel, null)
val dialog = builder.create()
dialog.setOnShowListener(this)
return dialog
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
val extraConf = activityResultMap.get(requestCode)
activityResultMap.remove(requestCode)
extraConf?.onActivityResult(requestCode and 0xFF, resultCode, data)
}
fun startExtraConfigurationActivityForResult(extraConf: TabConfiguration.ExtraConfiguration, intent: Intent, requestCode: Int) {
val requestCodeInternal = extraConf.position shl 8 and 0xFF00 or (requestCode and 0xFF)
activityResultMap.put(requestCodeInternal, extraConf)
startActivityForResult(intent, requestCodeInternal)
}
companion object {
const val TAG_EDIT_TAB = "edit_tab"

View File

@ -0,0 +1,68 @@
package org.mariotaku.twidere.model.tab.conf
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.UserListSelectorActivity
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.fragment.CustomTabsFragment.TabEditorDialogFragment
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.tab.TabConfiguration
import org.mariotaku.twidere.util.dagger.DependencyHolder
import org.mariotaku.twidere.util.display
import org.mariotaku.twidere.view.holder.TwoLineWithIconViewHolder
/**
* Created by mariotaku on 2016/11/28.
*/
class UserExtraConfiguration(key: String) : TabConfiguration.ExtraConfiguration(key) {
var value: ParcelableUser? = null
private set
private lateinit var viewHolder: TwoLineWithIconViewHolder
private lateinit var dependencyHolder: DependencyHolder
private lateinit var hintView: View
override fun onCreate(context: Context) {
super.onCreate(context)
this.dependencyHolder = DependencyHolder.get(context)
}
override fun onCreateView(context: Context, parent: ViewGroup): View {
return LayoutInflater.from(context).inflate(R.layout.layout_extra_config_user, parent, false)
}
override fun onViewCreated(context: Context, view: View, fragment: TabEditorDialogFragment) {
view.setOnClickListener {
val intent = Intent(INTENT_ACTION_SELECT_USER)
intent.putExtra(EXTRA_ACCOUNT_KEY, fragment.account.account_key)
intent.setClass(context, UserListSelectorActivity::class.java)
fragment.startExtraConfigurationActivityForResult(this@UserExtraConfiguration, intent, 1)
}
hintView = view.findViewById(R.id.selectUserHint)
viewHolder = TwoLineWithIconViewHolder(view.findViewById(R.id.listItem))
viewHolder.view.visibility = View.GONE
hintView.visibility = View.VISIBLE
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
when (requestCode) {
1 -> {
if (resultCode == Activity.RESULT_OK) {
val user: ParcelableUser = data.getParcelableExtra(EXTRA_USER)
viewHolder.display(user, dependencyHolder.mediaLoader, dependencyHolder.userColorNameManager, true)
viewHolder.view.visibility = View.VISIBLE
hintView.visibility = View.GONE
this.value = user
}
}
}
}
}

View File

@ -0,0 +1,70 @@
package org.mariotaku.twidere.model.tab.conf
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.UserListSelectorActivity
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.fragment.CustomTabsFragment.TabEditorDialogFragment
import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.model.tab.TabConfiguration
import org.mariotaku.twidere.util.dagger.DependencyHolder
import org.mariotaku.twidere.util.view.display
import org.mariotaku.twidere.view.holder.SimpleUserListViewHolder
/**
* Created by mariotaku on 2016/11/28.
*/
class UserListExtraConfiguration(key: String) : TabConfiguration.ExtraConfiguration(key) {
var value: ParcelableUserList? = null
private set
private lateinit var viewHolder: SimpleUserListViewHolder
private lateinit var dependencyHolder: DependencyHolder
private lateinit var hintView: View
override fun onCreate(context: Context) {
super.onCreate(context)
this.dependencyHolder = DependencyHolder.get(context)
}
override fun onCreateView(context: Context, parent: ViewGroup): View {
return LayoutInflater.from(context).inflate(R.layout.list_item_simple_user_list, parent, false)
}
override fun onViewCreated(context: Context, view: View, fragment: TabEditorDialogFragment) {
view.setOnClickListener {
val intent = Intent(INTENT_ACTION_SELECT_USER_LIST)
intent.putExtra(EXTRA_ACCOUNT_KEY, fragment.account.account_key)
intent.setClass(context, UserListSelectorActivity::class.java)
fragment.startExtraConfigurationActivityForResult(this@UserListExtraConfiguration, intent, 1)
}
hintView = view.findViewById(R.id.selectUserHint)
viewHolder = SimpleUserListViewHolder(view.findViewById(R.id.listItem))
viewHolder.itemView.visibility = View.GONE
hintView.visibility = View.VISIBLE
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
when (requestCode) {
1 -> {
if (resultCode == Activity.RESULT_OK) {
val userList: ParcelableUserList = data.getParcelableExtra(EXTRA_USER_LIST)
viewHolder.display(userList, dependencyHolder.mediaLoader,
dependencyHolder.userColorNameManager, true)
viewHolder.itemView.visibility = View.VISIBLE
hintView.visibility = View.GONE
this.value = userList
}
}
}
}
}

View File

@ -0,0 +1,27 @@
package org.mariotaku.twidere.util
import android.view.View
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.view.holder.TwoLineWithIconViewHolder
/**
* Created by mariotaku on 2016/12/1.
*/
fun TwoLineWithIconViewHolder.display(
user: ParcelableUser,
mediaLoader: MediaLoaderWrapper,
userColorNameManager: UserColorNameManager,
displayProfileImage: Boolean
) {
text1.setCompoundDrawablesWithIntrinsicBounds(0, 0,
Utils.getUserTypeIconRes(user.is_verified, user.is_protected), 0)
text1.text = userColorNameManager.getUserNickname(user.key, user.name)
text2.text = String.format("@%s", user.screen_name)
icon.visibility = if (displayProfileImage) View.VISIBLE else View.GONE
if (displayProfileImage) {
mediaLoader.displayProfileImage(icon, user)
} else {
mediaLoader.cancelDisplayTask(icon)
}
}

View File

@ -0,0 +1,22 @@
package org.mariotaku.twidere.util.view
import android.view.View
import org.mariotaku.twidere.R
import org.mariotaku.twidere.model.ParcelableUserList
import org.mariotaku.twidere.util.MediaLoaderWrapper
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.view.holder.SimpleUserListViewHolder
fun SimpleUserListViewHolder.display(userList: ParcelableUserList, mediaLoader: MediaLoaderWrapper,
userColorNameManager: UserColorNameManager,
displayProfileImage: Boolean) {
nameView.text = userList.name
createdByView.text = createdByView.context.getString(R.string.created_by,
userColorNameManager.getDisplayName(userList, false))
profileImageView.visibility = if (displayProfileImage) View.VISIBLE else View.GONE
if (displayProfileImage) {
mediaLoader.displayProfileImage(profileImageView, userList)
} else {
mediaLoader.cancelDisplayTask(profileImageView)
}
}

View File

@ -0,0 +1,24 @@
package org.mariotaku.twidere.view.holder
import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import kotlinx.android.synthetic.main.list_item_simple_user_list.view.*
/**
* Created by mariotaku on 2016/12/1.
*/
class SimpleUserListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val createdByView: TextView
val nameView: TextView
val profileImageView: ImageView
init {
nameView = itemView.name
createdByView = itemView.createdBy
profileImageView = itemView.profileImage
}
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?selectableItemBackground"
android:minHeight="?listPreferredItemHeight">
<include layout="@layout/list_item_simple_user"/>
<TextView
android:id="@+id/selectUserHint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="@dimen/element_spacing_normal"
android:text="@string/select_user"
android:textAppearance="?android:textAppearanceMedium"
android:textColor="?android:textColorPrimary"/>
</FrameLayout>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?selectableItemBackground"
android:minHeight="?listPreferredItemHeight">
<include layout="@layout/list_item_simple_user_list"/>
<TextView
android:id="@+id/selectUserListHint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="@dimen/element_spacing_normal"
android:text="@string/select_user_list"
android:textAppearance="?android:textAppearanceMedium"
android:textColor="?android:textColorPrimary"/>
</FrameLayout>

View File

@ -18,12 +18,13 @@
-->
<LinearLayout
android:id="@+id/listItem"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:listPreferredItemHeight"
android:minHeight="?listPreferredItemHeight"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal">
@ -50,7 +51,7 @@
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:textColorPrimary"
tools:text="User name"/>
@ -59,7 +60,7 @@
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="\@screenname"/>
</LinearLayout>

View File

@ -23,6 +23,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:minHeight="?listPreferredItemHeight"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal">
@ -41,8 +42,8 @@
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:paddingBottom="@dimen/element_spacing_xsmall"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"
@ -52,11 +53,11 @@
android:id="@+id/createdBy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:paddingTop="@dimen/element_spacing_xsmall"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
tools:text="Created by Mariotaku"/>
tools:text="Created by User"/>
</LinearLayout>
<org.mariotaku.twidere.view.ProfileImageView
@ -64,7 +65,10 @@
style="?profileImageStyle"
android:layout_width="@dimen/icon_size_card_list_item"
android:layout_height="@dimen/icon_size_card_list_item"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginStart="@dimen/element_spacing_normal"
android:layout_weight="0"
android:contentDescription="@string/profile_image"
android:scaleType="fitCenter"/>
android:scaleType="fitCenter"
tools:src="@mipmap/ic_launcher"/>
</LinearLayout>