added restart confirm

This commit is contained in:
Mariotaku Lee 2015-04-26 18:55:41 +08:00
parent e2b0f62f93
commit 3c8f7d007f
48 changed files with 451 additions and 125 deletions

View File

@ -652,7 +652,7 @@
android:authorities="twidere"
android:exported="true"
android:grantUriPermissions="true"
android:label="@string/label_tweetstore_provider"
android:label="@string/label_data_provider"
tools:ignore="ExportedContentProvider"/>
<provider
android:name=".provider.TwidereCommandProvider"

View File

@ -273,9 +273,10 @@ public abstract class BasePreferenceActivity extends AppCompatPreferenceActivity
final int themeColor = getCurrentThemeColor();
final int themeId = getCurrentThemeResourceId();
final String option = getThemeBackgroundOption();
final int titleColor = ThemeUtils.getContrastActionBarTitleColor(this, themeId, themeColor);
final int actionBarItemsColor = ThemeUtils.getContrastActionBarItemColor(this, themeId, themeColor);
ThemeUtils.applyActionBarBackground(actionBar, this, themeId, themeColor, option, isActionBarOutlineEnabled());
ThemeUtils.setActionBarItemsColor(getWindow(), actionBar, actionBarItemsColor);
ThemeUtils.setActionBarColor(getWindow(), actionBar, titleColor, actionBarItemsColor);
}
private void setupTintStatusBar() {

View File

@ -20,9 +20,13 @@
package org.mariotaku.twidere.activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
@ -62,12 +66,18 @@ import java.util.List;
public class SettingsActivity extends BasePreferenceActivity {
private static long HEADER_ID_RESTORE_ICON = 1001;
private static final long HEADER_ID_RESTORE_ICON = 1001;
private static final int RESULT_SETTINGS_CHANGED = 10;
private HeaderAdapter mAdapter;
private boolean mShouldNotifyChange;
public static void setShouldNotifyChange(Activity activity) {
if (!(activity instanceof SettingsActivity)) return;
((SettingsActivity) activity).setShouldNotifyChange(true);
}
public HeaderAdapter getHeaderAdapter() {
if (mAdapter != null) return mAdapter;
return mAdapter = new HeaderAdapter(this);
@ -114,7 +124,7 @@ public class SettingsActivity extends BasePreferenceActivity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && data != null && data.getBooleanExtra(EXTRA_CHANGED, false)) {
if (resultCode == RESULT_SETTINGS_CHANGED && data != null && data.getBooleanExtra(EXTRA_CHANGED, false)) {
setShouldNotifyChange(true);
}
super.onActivityResult(requestCode, resultCode, data);
@ -131,7 +141,7 @@ public class SettingsActivity extends BasePreferenceActivity {
pm.setComponentEnabledSetting(main2, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
Toast.makeText(this, R.string.icon_restored_message, Toast.LENGTH_SHORT).show();
finish();
onBackPressed();
return;
}
super.onHeaderClick(header, position);
@ -165,11 +175,25 @@ public class SettingsActivity extends BasePreferenceActivity {
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
if (getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT) != null) return false;
if (!isTopSettings()) return false;
getMenuInflater().inflate(R.menu.menu_settings, menu);
return true;
}
@Override
public void onBackPressed() {
if (isTopSettings() && shouldNotifyChange()) {
final RestartConfirmDialogFragment df = new RestartConfirmDialogFragment();
df.show(getFragmentManager().beginTransaction(), "restart_confirm");
return;
}
super.onBackPressed();
}
private boolean isTopSettings() {
return getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT) == null;
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
@ -198,11 +222,15 @@ public class SettingsActivity extends BasePreferenceActivity {
if (shouldNotifyChange()) {
final Intent data = new Intent();
data.putExtra(EXTRA_CHANGED, true);
setResult(RESULT_OK, data);
setResult(isTopSettings() ? RESULT_OK : RESULT_SETTINGS_CHANGED, data);
}
super.finish();
}
private void finishNoRestart() {
super.finish();
}
@Override
public void setListAdapter(final ListAdapter adapter) {
if (adapter == null) {
@ -227,11 +255,6 @@ public class SettingsActivity extends BasePreferenceActivity {
return super.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event);
}
public static void setShouldNotifyChange(Activity activity) {
if (!(activity instanceof SettingsActivity)) return;
((SettingsActivity) activity).setShouldNotifyChange(true);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
@ -273,6 +296,33 @@ public class SettingsActivity extends BasePreferenceActivity {
return mShouldNotifyChange;
}
public static class RestartConfirmDialogFragment extends DialogFragment implements DialogInterface.OnClickListener {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.app_restart_confirm);
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(R.string.dont_restart, this);
return builder.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
final SettingsActivity activity = (SettingsActivity) getActivity();
if (activity == null) return;
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
activity.finish();
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
activity.finishNoRestart();
break;
}
}
}
}
private static class HeaderAdapter extends BaseAdapter {
static final int HEADER_TYPE_NORMAL = 0;
@ -293,6 +343,16 @@ public class SettingsActivity extends BasePreferenceActivity {
mActionIconColor = ThemeUtils.getThemeForegroundColor(context);
}
private static int getHeaderType(final Header header) {
if (header.fragment != null || header.intent != null)
return HEADER_TYPE_NORMAL;
else if (header.title != null || header.titleRes != 0)
return HEADER_TYPE_CATEGORY;
else
return HEADER_TYPE_SPACE;
}
public void add(Header header) {
mHeaders.add(header);
notifyDataSetChanged();
@ -435,16 +495,6 @@ public class SettingsActivity extends BasePreferenceActivity {
return categoriesCount;
}
private static int getHeaderType(final Header header) {
if (header.fragment != null || header.intent != null)
return HEADER_TYPE_NORMAL;
else if (header.title != null || header.titleRes != 0)
return HEADER_TYPE_CATEGORY;
else
return HEADER_TYPE_SPACE;
}
private View inflateItemView(int viewType, ViewGroup parent) {
final int layoutRes;
switch (viewType) {

View File

@ -95,9 +95,10 @@ public class BaseDialogWhenLargeActivity extends BaseAppCompatActivity {
final int themeColor = getCurrentThemeColor();
final int themeId = getCurrentThemeResourceId();
final String option = getThemeBackgroundOption();
final int titleColor = ThemeUtils.getContrastActionBarTitleColor(this, themeId, themeColor);
final int actionBarItemsColor = ThemeUtils.getContrastActionBarItemColor(this, themeId, themeColor);
ThemeUtils.applyActionBarBackground(actionBar, this, themeId, themeColor, option, isActionBarOutlineEnabled());
ThemeUtils.setActionBarItemsColor(getWindow(), actionBar, actionBarItemsColor);
ThemeUtils.setActionBarColor(getWindow(), actionBar, titleColor, actionBarItemsColor);
}
private void setupTintStatusBar() {

View File

@ -293,7 +293,8 @@ public class LinkHandlerActivity extends BaseAppCompatActivity implements System
}
}
if (actionBarItemsColor != 0) {
ThemeUtils.setActionBarItemsColor(getWindow(), actionBar, actionBarItemsColor);
final int titleColor = ThemeUtils.getContrastActionBarTitleColor(this, themeId, themeColor);
ThemeUtils.setActionBarColor(getWindow(), actionBar, titleColor, actionBarItemsColor);
}
mActionBarItemsColor = actionBarItemsColor;
}

View File

@ -62,8 +62,8 @@ import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
import org.mariotaku.twidere.adapter.SourceAutoCompleteAdapter;
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.support.AbsContentListViewFragment;
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
import org.mariotaku.twidere.fragment.support.BaseSupportListFragment;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
import org.mariotaku.twidere.util.ContentValuesCreator;
@ -74,7 +74,7 @@ import org.mariotaku.twidere.util.Utils;
import static org.mariotaku.twidere.util.Utils.getDefaultAccountId;
public abstract class BaseFiltersFragment extends BaseSupportListFragment implements LoaderManager.LoaderCallbacks<Cursor>,
public abstract class BaseFiltersFragment extends AbsContentListViewFragment<SimpleCursorAdapter> implements LoaderManager.LoaderCallbacks<Cursor>,
MultiChoiceModeListener {
private static final String EXTRA_AUTO_COMPLETE_TYPE = "auto_complete_type";
@ -91,8 +91,6 @@ public abstract class BaseFiltersFragment extends BaseSupportListFragment implem
}
};
private ListView mListView;
private SimpleCursorAdapter mAdapter;
private ContentResolver mResolver;
private ActionMode mActionMode;
@ -103,26 +101,23 @@ public abstract class BaseFiltersFragment extends BaseSupportListFragment implem
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
mResolver = getContentResolver();
mAdapter = createListAdapter();
setListAdapter(mAdapter);
mListView = getListView();
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.setMultiChoiceModeListener(this);
setEmptyText(getString(R.string.no_rule));
final ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(this);
getLoaderManager().initLoader(0, null, this);
setListShown(false);
setRefreshEnabled(false);
showProgress();
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = super.onCreateView(inflater, container, savedInstanceState);
assert view != null;
final View lv = view.findViewById(android.R.id.list);
final ListView listView = (ListView) view.findViewById(R.id.list_view);
final Resources res = getResources();
final float density = res.getDisplayMetrics().density;
final int padding = (int) density * 16;
lv.setId(android.R.id.list);
lv.setPadding(padding, 0, padding, 0);
listView.setPadding(padding, 0, padding, 0);
return view;
}
@ -162,16 +157,17 @@ public abstract class BaseFiltersFragment extends BaseSupportListFragment implem
@Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
final ListView listView = getListView();
switch (item.getItemId()) {
case MENU_DELETE: {
final Expression where = Expression.in(new Column(Filters._ID), new RawItemArray(mListView.getCheckedItemIds()));
final Expression where = Expression.in(new Column(Filters._ID), new RawItemArray(listView.getCheckedItemIds()));
mResolver.delete(getContentUri(), where.getSQL(), null);
break;
}
case MENU_INVERSE_SELECTION: {
final SparseBooleanArray positions = mListView.getCheckedItemPositions();
for (int i = 0, j = mListView.getCount(); i < j; i++) {
mListView.setItemChecked(i, !positions.get(i));
final SparseBooleanArray positions = listView.getCheckedItemPositions();
for (int i = 0, j = listView.getCount(); i < j; i++) {
listView.setItemChecked(i, !positions.get(i));
}
return true;
}
@ -195,13 +191,19 @@ public abstract class BaseFiltersFragment extends BaseSupportListFragment implem
@Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
mAdapter.swapCursor(data);
setListShown(true);
final SimpleCursorAdapter adapter = getAdapter();
adapter.swapCursor(data);
if (data != null && data.getCount() > 0) {
showContent();
} else {
showError(R.drawable.ic_info_error_generic, getString(R.string.no_rule));
}
}
@Override
public void onLoaderReset(final Loader<Cursor> loader) {
mAdapter.swapCursor(null);
final SimpleCursorAdapter adapter = getAdapter();
adapter.swapCursor(null);
}
@Override
@ -230,15 +232,23 @@ public abstract class BaseFiltersFragment extends BaseSupportListFragment implem
updateTitle(mode);
}
protected SimpleCursorAdapter createListAdapter() {
return new FilterListAdapter(getActivity());
@Override
public boolean isRefreshing() {
return false;
}
@NonNull
@Override
protected SimpleCursorAdapter onCreateAdapter(Context context, boolean compact) {
return new FilterListAdapter(context);
}
protected abstract String[] getContentColumns();
private void updateTitle(final ActionMode mode) {
if (mListView == null || mode == null || getActivity() == null) return;
final int count = mListView.getCheckedItemCount();
final ListView listView = getListView();
if (listView == null || mode == null || getActivity() == null) return;
final int count = listView.getCheckedItemCount();
mode.setTitle(getResources().getQuantityString(R.plurals.Nitems_selected, count, count));
}
@ -441,11 +451,6 @@ public abstract class BaseFiltersFragment extends BaseSupportListFragment implem
return Filters.Users.CONTENT_URI;
}
@Override
protected SimpleCursorAdapter createListAdapter() {
return new FilterUsersListAdapter(getActivity());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@ -460,6 +465,11 @@ public abstract class BaseFiltersFragment extends BaseSupportListFragment implem
return super.onOptionsItemSelected(item);
}
@NonNull
@Override
protected SimpleCursorAdapter onCreateAdapter(Context context, boolean isCompact) {
return new FilterUsersListAdapter(getActivity());
}
}
}

View File

@ -157,7 +157,7 @@ public abstract class AbsActivitiesFragment<Data> extends BaseSupportFragment im
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
return inflater.inflate(R.layout.fragment_content_recyclerview, container, false);
}
@Override

View File

@ -0,0 +1,253 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 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.fragment.support;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarOffsetListener;
import org.mariotaku.twidere.activity.support.BaseAppCompatActivity;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.util.ContentListScrollListener.ContentListSupport;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereColorUtils;
import org.mariotaku.twidere.util.Utils;
/**
* Created by mariotaku on 15/4/16.
*/
public abstract class AbsContentListViewFragment<A extends ListAdapter> extends BaseSupportFragment
implements OnRefreshListener, RefreshScrollTopInterface, ControlBarOffsetListener,
ContentListSupport {
private View mProgressContainer;
private SwipeRefreshLayout mSwipeRefreshLayout;
private ListView mListView;
private View mErrorContainer;
private ImageView mErrorIconView;
private TextView mErrorTextView;
private A mAdapter;
// Data fields
private Rect mSystemWindowsInsets = new Rect();
@Override
public void onControlBarOffsetChanged(IControlBarActivity activity, float offset) {
updateRefreshProgressOffset();
}
@Override
public void onRefresh() {
triggerRefresh();
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
updateRefreshProgressOffset();
}
@Override
public boolean scrollToStart() {
mListView.setSelectionFromTop(0, 0);
// mListView.stopScroll();
setControlVisible(true);
return true;
}
@Override
public void setControlVisible(boolean visible) {
final FragmentActivity activity = getActivity();
if (activity instanceof BaseAppCompatActivity) {
((BaseAppCompatActivity) activity).setControlBarVisibleAnimate(visible);
}
}
@Override
public A getAdapter() {
return mAdapter;
}
@Override
public abstract boolean isRefreshing();
public void setRefreshing(final boolean refreshing) {
final boolean currentRefreshing = mSwipeRefreshLayout.isRefreshing();
if (!currentRefreshing) {
updateRefreshProgressOffset();
}
if (refreshing == currentRefreshing) return;
mSwipeRefreshLayout.setRefreshing(refreshing);
}
@Override
public void onLoadMoreContents() {
setRefreshEnabled(false);
}
public final ListView getListView() {
return mListView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).registerControlBarOffsetListener(this);
}
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_content_listview, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final View view = getView();
if (view == null) throw new AssertionError();
final Context context = view.getContext();
final boolean compact = Utils.isCompactCards(context);
final int backgroundColor = ThemeUtils.getThemeBackgroundColor(context);
final int colorRes = TwidereColorUtils.getContrastYIQ(backgroundColor,
R.color.bg_refresh_progress_color_light, R.color.bg_refresh_progress_color_dark);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.setColorSchemeColors(ThemeUtils.getUserAccentColor(context));
mSwipeRefreshLayout.setProgressBackgroundColorSchemeResource(colorRes);
mAdapter = onCreateAdapter(context, compact);
mListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
updateRefreshProgressOffset();
}
return false;
}
});
mListView.setAdapter((ListAdapter) mAdapter);
}
@Override
public void onBaseViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onBaseViewCreated(view, savedInstanceState);
mProgressContainer = view.findViewById(R.id.progress_container);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_layout);
mListView = (ListView) view.findViewById(R.id.list_view);
mErrorContainer = view.findViewById(R.id.error_container);
mErrorIconView = (ImageView) view.findViewById(R.id.error_icon);
mErrorTextView = (TextView) view.findViewById(R.id.error_text);
}
@Override
public void onDetach() {
final FragmentActivity activity = getActivity();
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).unregisterControlBarOffsetListener(this);
}
super.onDetach();
}
@Override
protected void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
mListView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
mErrorContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom);
mProgressContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom);
mSystemWindowsInsets.set(insets);
updateRefreshProgressOffset();
}
public void setRefreshEnabled(boolean enabled) {
mSwipeRefreshLayout.setEnabled(enabled);
}
@Override
public boolean triggerRefresh() {
return false;
}
@NonNull
protected abstract A onCreateAdapter(Context context, boolean compact);
protected final void showContent() {
mErrorContainer.setVisibility(View.GONE);
mProgressContainer.setVisibility(View.GONE);
mSwipeRefreshLayout.setVisibility(View.VISIBLE);
}
protected final void showProgress() {
mErrorContainer.setVisibility(View.GONE);
mProgressContainer.setVisibility(View.VISIBLE);
mSwipeRefreshLayout.setVisibility(View.GONE);
}
protected final void showError(int icon, CharSequence text) {
mErrorContainer.setVisibility(View.VISIBLE);
mProgressContainer.setVisibility(View.GONE);
mSwipeRefreshLayout.setVisibility(View.GONE);
mErrorIconView.setImageResource(icon);
mErrorTextView.setText(text);
}
protected final void showEmpty(int icon, CharSequence text) {
mErrorContainer.setVisibility(View.VISIBLE);
mProgressContainer.setVisibility(View.GONE);
mSwipeRefreshLayout.setVisibility(View.VISIBLE);
mErrorIconView.setImageResource(icon);
mErrorTextView.setText(text);
}
protected void updateRefreshProgressOffset() {
final FragmentActivity activity = getActivity();
if (!(activity instanceof IControlBarActivity) || mSystemWindowsInsets.top == 0 || mSwipeRefreshLayout == null
|| isRefreshing()) {
return;
}
final float density = getResources().getDisplayMetrics().density;
final int progressCircleDiameter = mSwipeRefreshLayout.getProgressCircleDiameter();
final IControlBarActivity control = (IControlBarActivity) activity;
final int controlBarOffsetPixels = Math.round(control.getControlBarHeight() * (1 - control.getControlBarOffset()));
final int swipeStart = (mSystemWindowsInsets.top - controlBarOffsetPixels) - progressCircleDiameter;
// 64: SwipeRefreshLayout.DEFAULT_CIRCLE_TARGET
final int swipeDistance = Math.round(64 * density);
mSwipeRefreshLayout.setProgressViewOffset(false, swipeStart, swipeStart + swipeDistance);
}
}

View File

@ -57,7 +57,7 @@ import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
/**
* Created by mariotaku on 15/4/16.
*/
public abstract class AbsContentListFragment<A extends IContentCardAdapter> extends BaseSupportFragment
public abstract class AbsContentRecyclerViewFragment<A extends IContentCardAdapter> extends BaseSupportFragment
implements OnRefreshListener, DrawerCallback, RefreshScrollTopInterface, ControlBarOffsetListener,
ContentListSupport {
@ -187,7 +187,7 @@ public abstract class AbsContentListFragment<A extends IContentCardAdapter> exte
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
return inflater.inflate(R.layout.fragment_content_recyclerview, container, false);
}
@Override

View File

@ -49,7 +49,7 @@ import static org.mariotaku.twidere.util.Utils.setMenuForStatus;
/**
* Created by mariotaku on 14/11/5.
*/
public abstract class AbsStatusesFragment<Data> extends AbsContentListFragment<AbsStatusesAdapter<Data>>
public abstract class AbsStatusesFragment<Data> extends AbsContentRecyclerViewFragment<AbsStatusesAdapter<Data>>
implements LoaderCallbacks<Data>, StatusAdapterListener, KeyboardShortcutCallback {
private final Object mStatusesBusCallback;

View File

@ -42,7 +42,7 @@ import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.UserViewHolder;
abstract class AbsUsersFragment<Data> extends AbsContentListFragment<AbsUsersAdapter<Data>>
abstract class AbsUsersFragment<Data> extends AbsContentRecyclerViewFragment<AbsUsersAdapter<Data>>
implements LoaderCallbacks<Data>, UserAdapterListener, KeyboardShortcutCallback {
private RecyclerViewNavigationHelper mRecyclerViewNavigationHelper;

View File

@ -72,7 +72,7 @@ import java.util.Set;
import static org.mariotaku.twidere.util.Utils.openMessageConversation;
public class DirectMessagesFragment extends AbsContentListFragment<MessageEntriesAdapter>
public class DirectMessagesFragment extends AbsContentRecyclerViewFragment<MessageEntriesAdapter>
implements LoaderCallbacks<Cursor>, MessageEntriesAdapterListener, KeyboardShortcutCallback {
// Listeners

View File

@ -131,7 +131,7 @@ public class UserMediaTimelineFragment extends BaseSupportFragment
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
return inflater.inflate(R.layout.fragment_content_recyclerview, container, false);
}
@Override

View File

@ -24,7 +24,7 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.OnScrollListener;
import org.mariotaku.twidere.adapter.iface.IContentCardAdapter;
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter;
/**
* Created by mariotaku on 15/3/15.
@ -70,17 +70,20 @@ public class ContentListScrollListener extends OnScrollListener {
}
private void notifyScrollStateChanged(RecyclerView recyclerView) {
final IContentCardAdapter adapter = mContentListSupport.getAdapter();
final Object adapter = mContentListSupport.getAdapter();
if (!(adapter instanceof ILoadMoreSupportAdapter)) return;
final ILoadMoreSupportAdapter loadMoreAdapter = (ILoadMoreSupportAdapter) adapter;
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (!mContentListSupport.isRefreshing() && adapter.isLoadMoreSupported() && !adapter.isLoadMoreIndicatorVisible()
&& layoutManager.findLastVisibleItemPosition() == adapter.getItemCount() - 1) {
if (!mContentListSupport.isRefreshing() && loadMoreAdapter.isLoadMoreSupported()
&& !loadMoreAdapter.isLoadMoreIndicatorVisible()
&& layoutManager.findLastVisibleItemPosition() == layoutManager.getItemCount() - 1) {
mContentListSupport.onLoadMoreContents();
}
}
public static interface ContentListSupport {
IContentCardAdapter getAdapter();
Object getAdapter();
boolean isRefreshing();

View File

@ -80,6 +80,8 @@ public class ThemeUtils implements Constants {
android.R.attr.activityOpenExitAnimation};
private static final int[] ANIM_CLOSE_STYLE_ATTRS = {android.R.attr.activityCloseEnterAnimation,
android.R.attr.activityCloseExitAnimation};
public static final int[] ATTRS_TEXT_COLOR_PRIMARY = {android.R.attr.textColorPrimary};
public static final int[] ATTRS_TEXT_COLOR_PRIMARY_INVERSE = {android.R.attr.textColorPrimaryInverse};
private ThemeUtils() {
throw new AssertionError();
@ -196,6 +198,8 @@ public class ThemeUtils implements Constants {
boolean outlineEnabled) {
// Very dirty implementation
if (!(modeCompat instanceof ActionModeImpl)) return;
// This call ensures TitleView created
modeCompat.setTitle(null);
try {
WindowDecorActionBar actionBar = null;
final Field[] fields = ActionModeImpl.class.getDeclaredFields();
@ -212,7 +216,6 @@ public class ThemeUtils implements Constants {
contextViewField.setAccessible(true);
final View contextView = (View) contextViewField.get(actionBar);
if (!(contextView instanceof ActionBarContextView)) return;
final ActionBarContextView actionBarContextView = (ActionBarContextView) contextView;
final TextView actionBarTitleView = (TextView) contextView.findViewById(android.support.v7.appcompat.R.id.action_bar_title);
final TextView actionBarSubtitleView = (TextView) contextView.findViewById(android.support.v7.appcompat.R.id.action_bar_subtitle);
final ImageView actionModeCloseButton = (ImageView) contextView.findViewById(android.support.v7.appcompat.R.id.action_mode_close_button);
@ -398,19 +401,23 @@ public class ThemeUtils implements Constants {
public static int getContrastActionBarItemColor(Context context, int theme, int color) {
if (isDarkTheme(theme) || TwidereColorUtils.getYIQLuminance(color) < 192) {
//return light text color
return Color.WHITE;
return context.getResources().getColor(R.color.action_icon_light);
}
//return dark text color
return Color.BLACK;
return context.getResources().getColor(R.color.action_icon_dark);
}
public static int getContrastActionBarTitleColor(Context context, int theme, int color) {
if (isDarkTheme(theme) || TwidereColorUtils.getYIQLuminance(color) < 192) {
if (isDarkTheme(theme)) {
//return light text color
return Color.WHITE;
}
return getTextColorPrimary(context);
} else if (TwidereColorUtils.getYIQLuminance(color) < 192) {
//return light text color
return getTextColorPrimaryInverse(context);
} else {
//return dark text color
return Color.BLACK;
return getTextColorPrimary(context);
}
}
public static int getDialogThemeResource(final Context context) {
@ -528,7 +535,16 @@ public class ThemeUtils implements Constants {
}
public static int getTextColorPrimary(final Context context) {
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.textColorPrimary});
final TypedArray a = context.obtainStyledAttributes(ATTRS_TEXT_COLOR_PRIMARY);
try {
return a.getColor(0, Color.TRANSPARENT);
} finally {
a.recycle();
}
}
public static int getTextColorPrimaryInverse(final Context context) {
final TypedArray a = context.obtainStyledAttributes(ATTRS_TEXT_COLOR_PRIMARY_INVERSE);
try {
return a.getColor(0, Color.TRANSPARENT);
} finally {
@ -874,14 +890,15 @@ public class ThemeUtils implements Constants {
}
}
public static void setActionBarItemsColor(Window window, android.support.v7.app.ActionBar actionBar, int itemColor) {
public static void setActionBarColor(Window window, android.support.v7.app.ActionBar actionBar,
int titleColor, int itemColor) {
final Drawable drawable = getActionBarHomeAsUpIndicator(actionBar);
if (drawable != null) {
drawable.setColorFilter(itemColor, Mode.SRC_ATOP);
}
actionBar.setHomeAsUpIndicator(drawable);
setActionBarTitleTextColor(window, itemColor);
setActionBarSubtitleTextColor(window, itemColor);
setActionBarTitleTextColor(window, titleColor);
setActionBarSubtitleTextColor(window, titleColor);
}
public static void setActionBarOverflowColor(Toolbar toolbar, int itemColor) {

View File

@ -41,7 +41,7 @@
<string name="select_account">اختيار حساب</string>
<string name="username">اسم المستخدم</string>
<string name="password">كلمة المرور</string>
<string name="label_tweetstore_provider">مزود قاعدة بيانات Twidere</string>
<string name="label_data_provider">مزود قاعدة بيانات Twidere</string>
<string name="label_refresh_service">تحديث الخدمة</string>
<string name="label_background_operation_service">خدمة التشغيل في الخلفية</string>
<string name="open_in_browser">فتح بالمستعرض</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Tria un compte</string>
<string name="username">Nom d\'usuari</string>
<string name="password">Contrasenya</string>
<string name="label_tweetstore_provider">Proveïdor de la base de dades de Twidere</string>
<string name="label_data_provider">Proveïdor de la base de dades de Twidere</string>
<string name="label_refresh_service">Actualitza el servei</string>
<string name="label_background_operation_service">Servei d\'execució en rerefons</string>
<string name="open_in_browser">Obrir al navegador</string>

View File

@ -40,7 +40,7 @@
<string name="select_account">Vyberte účet</string>
<string name="username">Uživatelské jméno</string>
<string name="password">Heslo</string>
<string name="label_tweetstore_provider">Poskytovatel databáze pro twidere</string>
<string name="label_data_provider">Poskytovatel databáze pro twidere</string>
<string name="label_refresh_service">Obnovit službu</string>
<string name="label_background_operation_service">Služba na pozadí</string>
<string name="open_in_browser">Otevřít v prohlížeči</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Account auswählen</string>
<string name="username">Benutzername</string>
<string name="password">Passwort</string>
<string name="label_tweetstore_provider">Twidere Datenbank Anbieter</string>
<string name="label_data_provider">Twidere Datenbank Anbieter</string>
<string name="label_refresh_service">Dienst aktualisieren</string>
<string name="label_background_operation_service">Hintergrunddienste</string>
<string name="open_in_browser">Im Browser öffnen</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Seleccione la cuenta</string>
<string name="username">Nombre de usuario</string>
<string name="password">Contraseña</string>
<string name="label_tweetstore_provider">Proveedor de base de datos de Twidere</string>
<string name="label_data_provider">Proveedor de base de datos de Twidere</string>
<string name="label_refresh_service">Recargar servicio</string>
<string name="label_background_operation_service">Servicio en segundo plano</string>
<string name="open_in_browser">Abrir en el navegador</string>

View File

@ -42,7 +42,7 @@
<string name="select_account">Valitse tili</string>
<string name="username">Käyttäjätunnus</string>
<string name="password">Salasana</string>
<string name="label_tweetstore_provider">Twideren tietokannan tarjoaja</string>
<string name="label_data_provider">Twideren tietokannan tarjoaja</string>
<string name="label_refresh_service">Päivitä palvelu</string>
<string name="label_background_operation_service">Taustatoimintojen palvelu</string>
<string name="open_in_browser">Avaa selaimessa</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Sélectionner un compte</string>
<string name="username">Nom d\'utilisateur</string>
<string name="password">Mot de passe</string>
<string name="label_tweetstore_provider">Fournisseur de base de données de Twidere</string>
<string name="label_data_provider">Fournisseur de base de données de Twidere</string>
<string name="label_refresh_service">Refraîcher le service</string>
<string name="label_background_operation_service">Service en arrière-plan</string>
<string name="open_in_browser">Ouvrir dans un navigateur</string>

View File

@ -37,7 +37,7 @@
<string name="select_account">खाता चुने</string>
<string name="username">यूज़रनेम</string>
<string name="password">पासवर्ड</string>
<string name="label_tweetstore_provider">ट्विदेर डेटाबेस प्रदाता</string>
<string name="label_data_provider">ट्विदेर डेटाबेस प्रदाता</string>
<string name="open_in_browser">ब्राउज़र में खोलें</string>
<string name="tap_to_load_more">छुए अधिक लोड करने के लिए।</string>
<string name="delete">मिटायें</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Válasszon fiókot</string>
<string name="username">Felhasználónév</string>
<string name="password">Jelszó</string>
<string name="label_tweetstore_provider">Twidere adatbázis szolgáltató</string>
<string name="label_data_provider">Twidere adatbázis szolgáltató</string>
<string name="label_refresh_service">Frissítő szolgáltatás</string>
<string name="label_background_operation_service">Háttér szolgáltatás</string>
<string name="open_in_browser">Megnyitás böngészőben</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Pilih akun</string>
<string name="username">Nama pengguna</string>
<string name="password">Kata Sandi</string>
<string name="label_tweetstore_provider">Penyedia database Twidere</string>
<string name="label_data_provider">Penyedia database Twidere</string>
<string name="label_refresh_service">Segarkan layanan</string>
<string name="label_background_operation_service">Latar Belakang layanan operasi</string>
<string name="open_in_browser">Buka di Browser</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Seleziona account</string>
<string name="username">Username</string>
<string name="password">Password</string>
<string name="label_tweetstore_provider">Provider database Twidere</string>
<string name="label_data_provider">Provider database Twidere</string>
<string name="label_refresh_service">Aggiorna servizio</string>
<string name="label_background_operation_service">Background operation service</string>
<string name="open_in_browser">Apri nel browser</string>

View File

@ -30,7 +30,7 @@
<string name="select_account">בחר חשבון</string>
<string name="username">שם משתמש</string>
<string name="password">סיסמה</string>
<string name="label_tweetstore_provider">ספק מסד הנתונים של Twidere</string>
<string name="label_data_provider">ספק מסד הנתונים של Twidere</string>
<string name="label_refresh_service">רענן שירות</string>
<string name="label_background_operation_service">שירות פעולה ברקע</string>
<string name="open_in_browser">פתח בדפדפן</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">アカウントを選択</string>
<string name="username">ユーザー名かメールアドレス</string>
<string name="password">パスワード</string>
<string name="label_tweetstore_provider">Twidereのデータベースストレージ</string>
<string name="label_data_provider">Twidereのデータベースストレージ</string>
<string name="label_refresh_service">サービスをリフレッシュ</string>
<string name="label_background_operation_service">バックグラウンド操作サービス</string>
<string name="open_in_browser">ブラウザで開く</string>

View File

@ -42,7 +42,7 @@
<string name="select_account">계정 선택</string>
<string name="username">사용자명</string>
<string name="password">패스워드</string>
<string name="label_tweetstore_provider">Twidere 데이터베이스 공급자</string>
<string name="label_data_provider">Twidere 데이터베이스 공급자</string>
<string name="label_refresh_service">서비스 새로고침</string>
<string name="label_background_operation_service">백그라운드 동작 서비스</string>
<string name="open_in_browser">브라우저에서 열기</string>

View File

@ -40,7 +40,7 @@
<string name="select_account">Selecteer account</string>
<string name="username">Gebruikersnaam</string>
<string name="password">Wachtwoord</string>
<string name="label_tweetstore_provider">Citeer</string>
<string name="label_data_provider">Citeer</string>
<string name="label_refresh_service">Vernieuw dienst</string>
<string name="label_background_operation_service">Achtergrond activiteiten service.</string>
<string name="open_in_browser">In browser openen</string>

View File

@ -34,7 +34,7 @@
<string name="select_account">Velg konto</string>
<string name="username">Brukernavn</string>
<string name="password">Passord</string>
<string name="label_tweetstore_provider">Twidere database leverandør</string>
<string name="label_data_provider">Twidere database leverandør</string>
<string name="label_refresh_service">Oppdaterings service</string>
<string name="open_in_browser">Åpne i nettleser</string>
<string name="tap_to_load_more">Trykk for å laste inn mer</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Wybierz konto</string>
<string name="username">Nazwa użytkownika</string>
<string name="password">Hasło</string>
<string name="label_tweetstore_provider">Dostawca bazy Twidere</string>
<string name="label_data_provider">Dostawca bazy Twidere</string>
<string name="label_refresh_service">Odświeżanie</string>
<string name="label_background_operation_service">Usługa operacji w tle</string>
<string name="open_in_browser">Otwórz w przeglądarce</string>

View File

@ -42,7 +42,7 @@
<string name="select_account">Selecione a conta</string>
<string name="username">Nome de Usuário</string>
<string name="password">Senha</string>
<string name="label_tweetstore_provider">Provedor de banco de dados do Twidere</string>
<string name="label_data_provider">Provedor de banco de dados do Twidere</string>
<string name="label_refresh_service">Atualizar serviço</string>
<string name="label_background_operation_service">Serviço de operação em segundo plano</string>
<string name="open_in_browser">Abrir no navegador</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Выберите учетную запись</string>
<string name="username">Имя пользователя</string>
<string name="password">Пароль</string>
<string name="label_tweetstore_provider">Провайдер базы данных Twitter</string>
<string name="label_data_provider">Провайдер базы данных Twitter</string>
<string name="label_refresh_service">Обновить сервис</string>
<string name="label_background_operation_service">Справочная служба</string>
<string name="open_in_browser">Открыть в браузере</string>

View File

@ -40,7 +40,7 @@
<string name="select_account">เลือกบัญชี</string>
<string name="username">ชื่อผู้ใช้</string>
<string name="password">รหัสผ่าน</string>
<string name="label_tweetstore_provider">ผู้ให้บริการญานข้อมูล Twidere</string>
<string name="label_data_provider">ผู้ให้บริการญานข้อมูล Twidere</string>
<string name="label_refresh_service">เรียกบริการอีกครั้ง</string>
<string name="label_background_operation_service">เซอร์วิสที่ทำงานเบื้องหลัง</string>
<string name="open_in_browser">เปิดในเบราเซอร์</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">Hesap seç</string>
<string name="username">Kullanıcı adı</string>
<string name="password">Şifre</string>
<string name="label_tweetstore_provider">Twidere veritabanı sağlayıcı</string>
<string name="label_data_provider">Twidere veritabanı sağlayıcı</string>
<string name="label_refresh_service">Servisi yenile</string>
<string name="label_background_operation_service">Arkaplan çalışma servisi</string>
<string name="open_in_browser">Tarayıcıda aç</string>

View File

@ -40,7 +40,7 @@
<string name="select_account">Виберіть обліковий запис</string>
<string name="username">Ім\'я користувача</string>
<string name="password">Пароль</string>
<string name="label_tweetstore_provider">Постачальник бази даних Твіттера</string>
<string name="label_data_provider">Постачальник бази даних Твіттера</string>
<string name="label_refresh_service">Оновити послугу</string>
<string name="label_background_operation_service">Послуга фонових операцій</string>
<string name="open_in_browser">Відкрити у браузері</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">选择帐号</string>
<string name="username">用户名</string>
<string name="password">密码</string>
<string name="label_tweetstore_provider">Twidere 数据库存储</string>
<string name="label_data_provider">Twidere 数据库存储</string>
<string name="label_refresh_service">刷新服务</string>
<string name="label_background_operation_service">后台操作服务</string>
<string name="open_in_browser">在浏览器中打开</string>

View File

@ -43,7 +43,7 @@
<string name="select_account">選擇帳號</string>
<string name="username">用戶名</string>
<string name="password">密碼</string>
<string name="label_tweetstore_provider">Twidere 資料庫存儲</string>
<string name="label_data_provider">Twidere 資料庫存儲</string>
<string name="label_refresh_service">刷新服務</string>
<string name="label_background_operation_service">後台操作服務</string>
<string name="open_in_browser">在瀏覽器中打開</string>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 B

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
~ Copyright (C) 2012-2015 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
@ -19,28 +18,28 @@
-->
<FrameLayout
android:id="@+id/fragment_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<include layout="@layout/layout_content_fragment_common" />
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false">
<org.mariotaku.twidere.view.RecyclerViewBackport
android:id="@+id/recycler_view"
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:focusable="true"
android:focusableInTouchMode="false"
android:scrollbars="vertical"/>
android:listSelector="?selectableItemBackground" />
</android.support.v4.widget.SwipeRefreshLayout>
<include layout="@layout/layout_content_fragment_common"/>
</FrameLayout>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
~ Copyright (C) 2012-2015 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

View File

@ -2,11 +2,6 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@id/inverse_selection"
android:icon="@drawable/ic_action_inverse_selection"
app:showAsAction="ifRoom|withText"
android:title="@string/inverse_selection"/>
<item
android:id="@id/delete"
android:icon="@drawable/ic_action_delete"

View File

@ -42,7 +42,7 @@
<string name="select_account">Select account</string>
<string name="username">Username</string>
<string name="password">Password</string>
<string name="label_tweetstore_provider">Twidere database provider</string>
<string name="label_data_provider">Twidere database provider</string>
<string name="label_refresh_service">Refresh service</string>
<string name="label_background_operation_service">Background operation service</string>
<string name="open_in_browser">Open in browser</string>
@ -377,7 +377,6 @@
<string name="profile_images">Profile images</string>
<string name="preview_images">Preview images</string>
<string name="preload_wifi_only">Preload using Wi-Fi only</string>
<string name="disable_tab_swipe">Disable tab swipe</string>
<string name="sign_in_method_introduction_title">How does it work?</string>
<string name="sign_in_method_introduction">Most clients like twicca open a browser asking you to type username and password, and then take you back to the clients. Sometimes this can become very inconvenient.\n\nTwidere uses simpler steps to sign in, without opening the browser. Don\'t worry about your password, Twidere will never store it, it\'s totally safe!</string>
<string name="quote_protected_status_notice">It\'s not recommended to quote protected tweets.</string>
@ -738,4 +737,6 @@
<string name="press_again_to_close">Press again to close</string>
<string name="name_not_set"><xliff:g id="name">%s</xliff:g> not set</string>
<string name="swipe_down_to_refresh">Swipe down to refresh</string>
<string name="app_restart_confirm">Twidere will restart to apply settings.</string>
<string name="dont_restart">Don\'t restart</string>
</resources>

View File

@ -71,11 +71,6 @@
android:value="true" />
</org.mariotaku.twidere.preference.LinkHighlightPreference>
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="true"
android:key="indicate_my_status"
android:order="29"
android:title="@string/indicate_your_status" />
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="false"
android:key="show_absolute_time"