improved theme

improved blackberry and meizu compatibility
This commit is contained in:
Mariotaku Lee 2015-04-30 17:55:03 +08:00
parent a52c8ccd9e
commit 46f85ce421
46 changed files with 1016 additions and 791 deletions

View File

@ -55,7 +55,6 @@ android {
repositories {
jcenter()
maven { url 'https://repo.commonsware.com.s3.amazonaws.com' }
maven { url 'https://github.com/suckgamony/RapidDecoder/raw/master/repository' }
maven { url "https://jitpack.io" }
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<android>
<config>
<overridenavbar />
</config>
</android>

View File

@ -0,0 +1,151 @@
/*
* 版本1.0
* 日期2014-10-16
* Copyright (C) 2010 中国广东省珠海市魅族科技有限公司版权所有
* 修改历史记录
* 2014-10-16 初始版本创建
*/
package com.meizu.flyme.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.app.ActionBar;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
/**
* <p>用以调用Flyme定制的API</p>
*
* @author MEIZU.SDK Team
*
*/
public class ActionBarProxy extends Proxy{
private static Class<?> sClass = ActionBar.class;
private static Method sSetBackButtonDrawableMethod;
private static Method sSetActionModeHeaderHiddenMethod;
private static Method sSetActionBarViewCollapsableMethod;
private static Method sSetOverFlowButtonDrawableMethod;
private static Method sSetTabsShowAtBottom;
/**
* 判断设备是否支持smart bar
* @return boolean true支持,false不支持
*/
public static boolean hasSmartBar() {
try {
Method method = Class.forName("android.os.Build").getMethod(
"hasSmartBar");
return ((Boolean) method.invoke(null)).booleanValue();
} catch (Exception e) {
}
return false;
}
/**
* 设置返回按钮图标
* @param actionbar 相应的ActionBar参数
* @param backIcon 返回按键的Icon
* @return boolean 执行结果
*/
public static boolean SetBackButtonDrawable(android.app.ActionBar actionbar,
Drawable backIcon) {
sSetBackButtonDrawableMethod = getMethod(sSetBackButtonDrawableMethod, sClass, "setBackButtonDrawable", new Class[] { Drawable.class });
return invoke(sSetBackButtonDrawableMethod, actionbar, backIcon);
}
/**
* 设置more按钮图标
* @return boolean 执行结果
*/
public static boolean SetOverFlowButtonDrawable(android.app.ActionBar actionbar,
Drawable drawable) {
sSetOverFlowButtonDrawableMethod = getMethod(sSetOverFlowButtonDrawableMethod, sClass, "setOverFlowButtonDrawable", new Class[] { Drawable.class });
return invoke(sSetOverFlowButtonDrawableMethod, actionbar, drawable);
}
/**
* 设置ActionMode顶栏是否隐藏
* @param bar 对应的ActionBar
* @param hide为true表示隐藏
* @return boolean 执行结果
*/
public static boolean setActionModeHeaderHidden(ActionBar bar, boolean hide) {
sSetActionModeHeaderHiddenMethod = getMethod(sSetActionModeHeaderHiddenMethod, sClass, "setActionModeHeaderHidden", boolean.class);
return invoke(sSetActionModeHeaderHiddenMethod, bar, hide);
}
/**
* 设置ActionBar顶栏无显示内容时是否隐藏
* @param bar
* @param collapsable
* @return boolen执行结果
*/
public static boolean setActionBarViewCollapsable(ActionBar bar, boolean collapsable) {
sSetActionBarViewCollapsableMethod = getMethod(sSetActionBarViewCollapsableMethod, sClass, "setActionBarViewCollapsable", boolean.class);
return invoke(sSetActionBarViewCollapsableMethod, bar, collapsable);
}
/**
* <p>
* 设置ActionBar Tabs显示在底栏不过需要配合
* android:uiOptions="splitActionBarWhenNarrow"
* <p>
* @param actionbar
* @param showAtBottom
* @return boolen 执行结果
*/
public static boolean setActionBarTabsShowAtBottom(
android.app.ActionBar actionbar, boolean showAtBottom) {
sSetTabsShowAtBottom = getMethod(sSetTabsShowAtBottom, sClass, "setTabsShowAtBottom", boolean.class);
return invoke(sSetTabsShowAtBottom, actionbar, showAtBottom);
}
/**
* 获取actionbar高度
* @param context 上下文
* @param actionbar 对应的ActionBar
* @return int ActionBar的高度值
*/
public static int getActionBarHeight(Context context, ActionBar actionbar) {
if(actionbar != null){
TypedValue tv = new TypedValue();
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize,
tv, true)) {
return TypedValue.complexToDimensionPixelSize(tv.data, context
.getResources().getDisplayMetrics());
}
return actionbar.getHeight();
}
return 0;
}
/**
* 获取smartbar高度
* @param context
* @param actionbar
* @return int SmartBar的高度值
*/
public static int getSmartBarHeight(Context context,ActionBar actionbar) {
if(actionbar != null){
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("mz_action_button_min_height");
int height = Integer.parseInt(field.get(obj).toString());
return context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
actionbar.getHeight();
}
return 0;
}
}

View File

@ -0,0 +1,35 @@
package com.meizu.flyme.reflect;
import java.lang.reflect.Method;
import android.content.Context;
import android.view.inputmethod.InputMethodManager;
/**
* @author MEIZU.SDK Team
*
*/
public class InputMethodProxy extends Proxy {
private final static String TAG = "InputMethod";
private static Class<?> sClass = InputMethodManager.class;
private static Method sSetMzInputThemeLight;
/**
* 设置导航栏和输入法背景颜色在App启动第一个Actiity onCreate方法中调用该方法执行成功后App中使用系统输入法都是白色样式
* @param context 上下文
* @param light 是否把导航栏和输入法背景设置为白色
* @return boolean 执行结果成功执行返回true
*/
public static boolean setInputThemeLight(Context context, boolean light) {
sSetMzInputThemeLight = getMethod(sSetMzInputThemeLight, sClass,
"setMzInputThemeLight", boolean.class);
InputMethodManager imm = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
return invoke(sSetMzInputThemeLight, imm, light);
}
return false;
}
}

View File

@ -0,0 +1,79 @@
/*
* 版本1.0
* 日期2014-10-16
* Copyright (C) 2010 中国广东省珠海市魅族科技有限公司版权所有
* 修改历史记录
* 2014-10-16 初始版本创建
*/
package com.meizu.flyme.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.app.Notification;
import android.app.Notification.Builder;
/**
* <p>用以调用Flyme定制的API</p>
*
* @author MEIZU.SDK Team
*
*/
public class NotificationProxy extends Proxy {
private static Class<?> sClass = Notification.Builder.class;
private static Field sField = null;
private static Object sObject = null;
private static Method sSetProgressBarStype = null;
private static Method sSetCircleProgressBarColor = null;
private static Method ssetCircleProgressRimColor = null;
/**
* 设置ProgressBar的类型
* @param builder 为Notification.Builder类
* @param isCircle true为圆环形false为普通直线形
*/
public static void setProgressBarStype(Builder builder, boolean isCircle){
try{
sField = sClass.getField("mFlymeNotificationBuilder");
sObject = sField.get(builder);
sSetProgressBarStype = sField.getType().getDeclaredMethod("setCircleProgressBar", boolean.class);
if(sObject != null){
invoke(sSetProgressBarStype, sObject, isCircle);
}
}catch(Exception ignore){
ignore.printStackTrace();
}
}
/**
* 设置圆环形ProgressBar活动进度条的颜色
* @param color 为颜色值
*/
public static void setCircleProgressBarColor(int color) {
try{
if(sField != null && sObject != null){
sSetCircleProgressBarColor = sField.getType().getDeclaredMethod("setCircleProgressBarColor", int.class);
invoke(sSetCircleProgressBarColor, sObject, color);
}
}catch(Exception ignore){
ignore.printStackTrace();
}
}
/**
* 设置圆环形ProgressBar外边环的颜色
* @param color 为颜色值
*/
public static void setCircleProgressRimColor(int color) {
try{
if(sField != null && sObject != null){
ssetCircleProgressRimColor = sField.getType().getDeclaredMethod("ssetCircleProgressRimColor", int.class);
invoke(ssetCircleProgressRimColor, sObject, color);
}
}catch(Exception ignore){
ignore.printStackTrace();
}
}
}

View File

@ -0,0 +1,50 @@
package com.meizu.flyme.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Proxy {
/**
* 获取方法
* @param method
* @param clazz
* @param name
* @param parameterTypes
* @return method
*/
protected static Method getMethod (Method method, Class<?> clazz, String name, Class<?>... parameterTypes) {
if (method == null) {
try {
method = clazz.getMethod(name, parameterTypes);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
return method;
}
/**
* 执行方法
* @param method 方法
* @param obj 对像
* @param args 参数
* @return boolean 执行结果
*/
protected static boolean invoke (Method method, Object obj, Object... args) {
if (method != null) {
try {
method.invoke(obj, args);
return true;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return false;
}
}

View File

@ -0,0 +1,106 @@
package com.meizu.flyme.reflect;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import java.lang.reflect.Field;
public class StatusBarProxy {
private final static String TAG = "StatusBar";
/**
* 设置状态栏图标为深色和魅族特定的文字风格
* @param window 需要设置的窗口
* @param dark 是否把状态栏颜色设置为深色
* @return boolean 成功执行返回true
*/
public static boolean setStatusBarDarkIcon(Window window, boolean dark) {
boolean result = false;
if (window != null) {
try {
WindowManager.LayoutParams lp = window.getAttributes();
Field darkFlag = WindowManager.LayoutParams.class
.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
Field meizuFlags = WindowManager.LayoutParams.class
.getDeclaredField("meizuFlags");
darkFlag.setAccessible(true);
meizuFlags.setAccessible(true);
int bit = darkFlag.getInt(null);
int value = meizuFlags.getInt(lp);
if (dark) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
window.setAttributes(lp);
result = true;
} catch (Exception e) {
Log.e(TAG, "setStatusBarDarkIcon: failed");
}
}
return result;
}
/**
* 设置沉浸式窗口设置成功后状态栏则透明显示
* @param window 需要设置的窗口
* @param immersive 是否把窗口设置为沉浸
* @return boolean 成功执行返回true
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public static boolean setImmersedWindow(Window window, boolean immersive) {
boolean result = false;
if (window != null) {
WindowManager.LayoutParams lp = window.getAttributes();
int trans_status = 0;
Field flags;
if (android.os.Build.VERSION.SDK_INT < 19) {
try {
trans_status = 1 << 6;
flags = lp.getClass().getDeclaredField("meizuFlags");
flags.setAccessible(true);
int value = flags.getInt(lp);
if (immersive) {
value = value | trans_status;
} else {
value = value & ~trans_status;
}
flags.setInt(lp, value);
result = true;
} catch (Exception e) {
Log.e(TAG, "setImmersedWindow: failed");
}
} else {
lp.flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
window.setAttributes(lp);
result = true;
}
}
return result;
}
/**
* 获取状态栏高度
* @param context 上下文
* @return int 状态栏高度
*/
public static int getStatusBarHeight(Context context) {
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("status_bar_height");
int height = Integer.parseInt(field.get(obj).toString());
return context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return 75;
}
}

View File

@ -0,0 +1,61 @@
package com.meizu.flyme.reflect;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import android.app.WallpaperManager;
import android.content.Context;
public class WallpaperManagerProxy extends Proxy {
private final static String TAG = "WallpaperManagerProxy";
private static Class<?> sClass = WallpaperManager.class;
private static Method sSetLockWallpaper;
/**
* 从参数所提供的路径读取图片并设置为锁屏界面
* @param context 上下文
* @param path 图片的路径
* @return boolean 成功执行返回true
*/
public static boolean setLockWallpaper(Context context, String path) {
boolean result = false;
WallpaperManager wm = WallpaperManager.getInstance(context);
try {
InputStream is = new FileInputStream(path);
sSetLockWallpaper = getMethod(sSetLockWallpaper, sClass,
"setStreamToLockWallpaper", InputStream.class);
if (wm != null) {
result = invoke(sSetLockWallpaper, wm, is);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return result;
}
/**
* 从参数所提供的路径读取图片并设置为Home界面
* @param context 上下文
* @param path 图片的路径
* @return boolean 成功执行返回true
*/
public static boolean setHomeWallpaper(Context context, String path) {
boolean result = false;
WallpaperManager wm = WallpaperManager.getInstance(context);
try {
InputStream is = new FileInputStream(path);
wm.setStream(is);
result = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -38,6 +38,8 @@ import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout;
import com.meizu.flyme.reflect.StatusBarProxy;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
@ -45,6 +47,7 @@ import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereColorUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.support.ViewSupport;
import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle;
@ -291,13 +294,15 @@ public abstract class BasePreferenceActivity extends AppCompatPreferenceActivity
private void setupTintStatusBar() {
if (mMainContent == null) return;
final int color = getCurrentThemeColor();
final int alpha = ThemeUtils.isTransparentBackground(getThemeBackgroundOption()) ? getCurrentThemeBackgroundAlpha() : 0xFF;
final int statusBarColor;
if (ThemeUtils.isDarkTheme(getCurrentThemeResourceId())) {
mMainContent.setColor(getResources().getColor(R.color.background_color_action_bar_dark), alpha);
statusBarColor = getResources().getColor(R.color.background_color_action_bar_dark);
} else {
mMainContent.setColor(color, alpha);
statusBarColor = getCurrentThemeColor();
}
mMainContent.setColor(statusBarColor, alpha);
StatusBarProxy.setStatusBarDarkIcon(getWindow(), TwidereColorUtils.getYIQLuminance(statusBarColor) > ThemeUtils.ACCENT_COLOR_THRESHOLD);
mMainContent.setDrawShadow(false);
mMainContent.setDrawColor(true);

View File

@ -1,132 +0,0 @@
/*
* 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.activity.support;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.WindowManager.LayoutParams;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.support.ViewSupport;
import org.mariotaku.twidere.view.iface.TintedStatusLayout;
/**
* Created by mariotaku on 15/4/17.
*/
public class BaseDialogWhenLargeActivity extends BaseAppCompatActivity {
private TintedStatusLayout mMainContent;
@Override
public int getThemeResourceId() {
return ThemeUtils.getDialogWhenLargeThemeResource(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
setupWindow();
super.onCreate(savedInstanceState);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
final boolean result = super.onPrepareOptionsMenu(menu);
if (!shouldSetActionItemColor()) return result;
final Toolbar toolbar = peekActionBarToolbar();
if (toolbar != null) {
final int themeColor = getCurrentThemeColor();
final int themeId = getCurrentThemeResourceId();
final int itemColor = ThemeUtils.getContrastActionBarItemColor(this, themeId, themeColor);
ThemeUtils.setActionBarOverflowColor(toolbar, itemColor);
ThemeUtils.wrapToolbarMenuIcon(ViewSupport.findViewByType(toolbar, ActionMenuView.class), itemColor, itemColor);
}
return result;
}
@Override
public void onContentChanged() {
super.onContentChanged();
mMainContent = (TintedStatusLayout) findViewById(R.id.main_content);
setupTintStatusBar();
}
protected TintedStatusLayout getMainContent() {
return mMainContent;
}
protected boolean isActionBarOutlineEnabled() {
return true;
}
protected boolean shouldSetActionItemColor() {
return true;
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
setupActionBar();
}
private void setupActionBar() {
final ActionBar actionBar = getSupportActionBar();
if (actionBar == null) return;
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());
final Toolbar toolbar = peekActionBarToolbar();
if (toolbar != null) {
ThemeUtils.setToolBarColor(toolbar, titleColor, actionBarItemsColor);
} else {
ThemeUtils.setActionBarColor(getWindow(), getSupportActionBar(), titleColor, actionBarItemsColor);
}
}
private void setupTintStatusBar() {
if (mMainContent == null) return;
final int color = getCurrentThemeColor();
final int alpha = ThemeUtils.isTransparentBackground(getThemeBackgroundOption()) ? getCurrentThemeBackgroundAlpha() : 0xFF;
if (ThemeUtils.isDarkTheme(getCurrentThemeResourceId())) {
mMainContent.setColor(getResources().getColor(R.color.background_color_action_bar_dark), alpha);
} else {
mMainContent.setColor(color, alpha);
}
mMainContent.setDrawShadow(false);
mMainContent.setDrawColor(true);
mMainContent.setFactor(1);
}
private void setupWindow() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
}

View File

@ -61,7 +61,6 @@ import android.support.v7.widget.RecyclerView.ItemDecoration;
import android.support.v7.widget.RecyclerView.State;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.text.Editable;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
@ -203,25 +202,6 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL
return ThemeUtils.getComposeThemeResource(this);
}
public static boolean isFinishedComposing(CharSequence text) {
if (!(text instanceof Spanned)) return true;
final Spanned spanned = (Spanned) text;
try {
final Class<?> cls = Class.forName("android.text.style.SpellCheckSpan");
if (spanned.getSpans(0, spanned.length(), cls).length > 0) return false;
} catch (Exception ignored) {
}
try {
final Class<?> cls = Class.forName("android.view.inputmethod.ComposingText");
if (spanned.getSpans(0, spanned.length(), cls).length > 0) return false;
} catch (Exception ignored) {
}
// if (spanned.getSpans(0, spanned.length(), SpanWatcher.class).length > 0) return false;
return true;
}
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
switch (requestCode) {
@ -620,6 +600,49 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL
linearLayoutManager.setStackFromEnd(true);
mAccountSelector.setLayoutManager(linearLayoutManager);
mAccountSelector.addItemDecoration(new SpacingItemDecoration(this));
mAccountSelector.setItemAnimator(new RecyclerView.ItemAnimator() {
@Override
public void runPendingAnimations() {
}
@Override
public boolean animateRemove(ViewHolder holder) {
return false;
}
@Override
public boolean animateAdd(ViewHolder holder) {
return false;
}
@Override
public boolean animateMove(ViewHolder holder, int fromX, int fromY, int toX, int toY) {
Log.d(LOGTAG, String.format("animateMove"));
return false;
}
@Override
public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) {
Log.d(LOGTAG, String.format("animateChange"));
return false;
}
@Override
public void endAnimation(ViewHolder item) {
Log.d(LOGTAG, String.format("endAnimation"));
}
@Override
public void endAnimations() {
}
@Override
public boolean isRunning() {
return false;
}
});
mAccountsAdapter = new AccountIconsAdapter(this);
mAccountSelector.setAdapter(mAccountsAdapter);
mAccountsAdapter.setAccounts(ParcelableAccount.getAccounts(this, false, false));
@ -1271,6 +1294,7 @@ public class ComposeActivity extends ThemedFragmentActivity implements LocationL
private ParcelableAccount[] mAccounts;
public AccountIconsAdapter(ComposeActivity activity) {
setHasStableIds(true);
mActivity = activity;
mInflater = activity.getLayoutInflater();
mImageLoader = TwidereApplication.getInstance(activity).getMediaLoaderWrapper();

View File

@ -64,6 +64,7 @@ import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.CanvasTransformer;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.OnClosedListener;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.OnOpenedListener;
import com.meizu.flyme.reflect.StatusBarProxy;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
@ -340,15 +341,15 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mMultiSelectHandler = new MultiSelectEventHandler(this);
mMultiSelectHandler.dispatchOnCreate();
if (!Utils.hasAccount(this)) {
final Intent signInIntent = new Intent(INTENT_ACTION_TWITTER_LOGIN);
signInIntent.setClass(this, SignInActivity.class);
startActivity(signInIntent);
finish();
return;
} else {
notifyAccountsChanged();
}
// if (!Utils.hasAccount(this)) {
// final Intent signInIntent = new Intent(INTENT_ACTION_TWITTER_LOGIN);
// signInIntent.setClass(this, SignInActivity.class);
// startActivity(signInIntent);
// finish();
// return;
// } else {
// notifyAccountsChanged();
// }
final Intent intent = getIntent();
if (openSettingsWizard()) {
finish();
@ -366,7 +367,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
ThemeUtils.applyBackground(mTabIndicator);
mPagerAdapter = new SupportTabsAdapter(this, getSupportFragmentManager(), mTabIndicator, mTabColumns);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setOffscreenPageLimit(3);
// mViewPager.setOffscreenPageLimit(3);
mTabIndicator.setViewPager(mViewPager);
mTabIndicator.setOnPageChangeListener(this);
mTabIndicator.setColumns(mTabColumns);
@ -490,14 +491,6 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
}
public void notifyAccountsChanged() {
if (mPreferences == null) return;
// final long[] accountIds = getAccountIds(this);
// final long default_id = mPreferences.getLong(KEY_DEFAULT_ACCOUNT_ID, -1);
// if (accountIds == null || accountIds.length == 0) {
// finish();
// } else if (accountIds.length > 0 && !ArrayUtils.contains(accountIds, default_id)) {
// mPreferences.edit().putLong(KEY_DEFAULT_ACCOUNT_ID, accountIds[0]).apply();
// }
}
@Subscribe
@ -834,6 +827,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
mColorStatusFrameLayout.setDrawColor(true);
mColorStatusFrameLayout.setDrawShadow(false);
mColorStatusFrameLayout.setColor(statusBarColor, actionBarAlpha);
StatusBarProxy.setStatusBarDarkIcon(getWindow(), TwidereColorUtils.getYIQLuminance(statusBarColor) > ThemeUtils.ACCENT_COLOR_THRESHOLD);
mColorStatusFrameLayout.setFactor(1);
mTabIndicator.setAlpha(actionBarAlpha / 255f);
mActionsButton.setAlpha(actionBarAlpha / 255f);

View File

@ -43,6 +43,8 @@ import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import com.meizu.flyme.reflect.StatusBarProxy;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
@ -56,6 +58,7 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallb
import org.mariotaku.twidere.util.MultiSelectEventHandler;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereActionModeForChildListener;
import org.mariotaku.twidere.util.TwidereColorUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.support.ActivitySupport;
import org.mariotaku.twidere.util.support.ActivitySupport.TaskDescriptionCompat;
@ -273,18 +276,6 @@ public class LinkHandlerActivity extends BaseAppCompatActivity implements System
actionBar.setSubtitle(subtitle);
}
@Override
protected boolean onPrepareOptionsPanel(View view, Menu menu) {
final Toolbar toolbar = peekActionBarToolbar();
final boolean result = super.onPrepareOptionsPanel(view, menu);
if (mActionBarItemsColor != 0 && toolbar != null) {
toolbar.setTitleTextColor(mActionBarItemsColor);
toolbar.setSubtitleTextColor(mActionBarItemsColor);
ThemeUtils.setActionBarOverflowColor(toolbar, mActionBarItemsColor);
}
return result;
}
@Override
public void onContentChanged() {
super.onContentChanged();
@ -363,9 +354,14 @@ public class LinkHandlerActivity extends BaseAppCompatActivity implements System
break;
}
}
if (actionBarItemsColor != 0) {
if (actionBarItemsColor != 0 && shouldSetActionItemColor()) {
final int titleColor = ThemeUtils.getContrastActionBarTitleColor(this, themeId, themeColor);
ThemeUtils.setActionBarColor(getWindow(), actionBar, titleColor, actionBarItemsColor);
final Toolbar toolbar = peekActionBarToolbar();
if (toolbar != null) {
ThemeUtils.setToolBarColor(toolbar, titleColor, actionBarItemsColor);
} else {
ThemeUtils.setActionBarColor(getWindow(), getSupportActionBar(), titleColor, actionBarItemsColor);
}
}
mActionBarItemsColor = actionBarItemsColor;
}
@ -380,13 +376,15 @@ public class LinkHandlerActivity extends BaseAppCompatActivity implements System
mMainContent.setDrawShadow(false);
mMainContent.setDrawColor(true);
mMainContent.setFactor(1);
final int color = getCurrentThemeColor();
final int alpha = ThemeUtils.isTransparentBackground(getThemeBackgroundOption()) ? getCurrentThemeBackgroundAlpha() : 0xFF;
final int statusBarColor;
if (ThemeUtils.isDarkTheme(getCurrentThemeResourceId())) {
mMainContent.setColor(getResources().getColor(R.color.background_color_action_bar_dark), alpha);
statusBarColor = getResources().getColor(R.color.background_color_action_bar_dark);
} else {
mMainContent.setColor(color, alpha);
statusBarColor = getCurrentThemeColor();
}
mMainContent.setColor(statusBarColor, alpha);
StatusBarProxy.setStatusBarDarkIcon(getWindow(), TwidereColorUtils.getYIQLuminance(statusBarColor) > ThemeUtils.ACCENT_COLOR_THRESHOLD);
break;
}
}

View File

@ -56,6 +56,8 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.meizu.flyme.reflect.StatusBarProxy;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.SettingsActivity;
import org.mariotaku.twidere.app.TwidereApplication;
@ -70,6 +72,7 @@ import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.AuthenticityTokenEx
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.WrongUserPassException;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereColorUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.net.OkHttpClientFactory;
import org.mariotaku.twidere.util.net.TwidereHostResolverFactory;
@ -556,13 +559,15 @@ public class SignInActivity extends BaseAppCompatActivity implements TwitterCons
private void setupTintStatusBar() {
if (mMainContent == null) return;
final int color = getCurrentThemeColor();
final int alpha = ThemeUtils.isTransparentBackground(getThemeBackgroundOption()) ? getCurrentThemeBackgroundAlpha() : 0xFF;
final int statusBarColor;
if (ThemeUtils.isDarkTheme(getCurrentThemeResourceId())) {
mMainContent.setColor(getResources().getColor(R.color.background_color_action_bar_dark), alpha);
statusBarColor = getResources().getColor(R.color.background_color_action_bar_dark);
} else {
mMainContent.setColor(color, alpha);
statusBarColor = getCurrentThemeColor();
}
mMainContent.setColor(statusBarColor, alpha);
StatusBarProxy.setStatusBarDarkIcon(getWindow(), TwidereColorUtils.getYIQLuminance(statusBarColor) > ThemeUtils.ACCENT_COLOR_THRESHOLD);
mMainContent.setDrawShadow(false);
mMainContent.setDrawColor(true);

View File

@ -203,7 +203,6 @@ public class TwidereApplication extends MultiDexApplication implements Constants
public SQLiteDatabase getSQLiteDatabase() {
if (mDatabase != null) return mDatabase;
StrictModeUtils.checkDiskIO();
return mDatabase = getSQLiteOpenHelper().getWritableDatabase();
}

View File

@ -93,8 +93,8 @@ public abstract class AbsContentListViewFragment<A extends ListAdapter> extends
@Override
public void setControlVisible(boolean visible) {
final FragmentActivity activity = getActivity();
if (activity instanceof BaseAppCompatActivity) {
((BaseAppCompatActivity) activity).setControlBarVisibleAnimate(visible);
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).setControlBarVisibleAnimate(visible);
}
}

View File

@ -130,8 +130,8 @@ public abstract class AbsContentRecyclerViewFragment<A extends IContentCardAdapt
@Override
public void setControlVisible(boolean visible) {
final FragmentActivity activity = getActivity();
if (activity instanceof BaseAppCompatActivity) {
((BaseAppCompatActivity) activity).setControlBarVisibleAnimate(visible);
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).setControlBarVisibleAnimate(visible);
}
}

View File

@ -45,7 +45,7 @@ import org.mariotaku.querybuilder.Columns.Column;
import org.mariotaku.querybuilder.Expression;
import org.mariotaku.querybuilder.RawItemArray;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.BaseAppCompatActivity;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.activity.support.HomeActivity;
import org.mariotaku.twidere.adapter.MessageEntriesAdapter;
import org.mariotaku.twidere.adapter.MessageEntriesAdapter.DirectMessageEntry;
@ -103,8 +103,8 @@ public class DirectMessagesFragment extends AbsContentRecyclerViewFragment<Messa
@Override
public void setControlVisible(boolean visible) {
final FragmentActivity activity = getActivity();
if (activity instanceof BaseAppCompatActivity) {
((BaseAppCompatActivity) activity).setControlBarVisibleAnimate(visible);
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).setControlBarVisibleAnimate(visible);
}
}

View File

@ -0,0 +1,115 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.support;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.graphic.EmptyDrawable;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.TabPagerIndicator;
public class ListsFragment extends BaseSupportFragment implements RefreshScrollTopInterface,
SupportFragmentCallback, SystemWindowsInsetsCallback {
private ViewPager mViewPager;
private TabPagerIndicator mPagerIndicator;
private View mPagerOverlay;
private SupportTabsAdapter mPagerAdapter;
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Bundle args = getArguments();
final FragmentActivity activity = getActivity();
mPagerAdapter = new SupportTabsAdapter(activity, getChildFragmentManager(), null, 1);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setOffscreenPageLimit(2);
mPagerIndicator.setViewPager(mViewPager);
mPagerIndicator.setTabDisplayOption(TabPagerIndicator.LABEL);
mPagerAdapter.addTab(UserListsFragment.class, args, getString(R.string.follows), null, 0, null);
mPagerAdapter.addTab(UserListMembershipsFragment.class, args, getString(R.string.belongs_to), 0, 1, null);
ThemeUtils.initPagerIndicatorAsActionBarTab(activity, mPagerIndicator, mPagerOverlay);
ThemeUtils.setCompatToolbarOverlay(activity, new EmptyDrawable());
ThemeUtils.setCompatContentViewOverlay(activity, new EmptyDrawable());
ThemeUtils.setWindowOverlayViewOverlay(activity, new EmptyDrawable());
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_content_pages, container, false);
}
@Override
public void onBaseViewCreated(final View view, final Bundle savedInstanceState) {
super.onBaseViewCreated(view, savedInstanceState);
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
mPagerIndicator = (TabPagerIndicator) view.findViewById(R.id.view_pager_tabs);
mPagerOverlay = view.findViewById(R.id.pager_window_overlay);
}
@Override
public boolean scrollToStart() {
final Fragment fragment = getCurrentVisibleFragment();
if (!(fragment instanceof RefreshScrollTopInterface)) return false;
((RefreshScrollTopInterface) fragment).scrollToStart();
return true;
}
@Override
public boolean triggerRefresh() {
final Fragment fragment = getCurrentVisibleFragment();
if (!(fragment instanceof RefreshScrollTopInterface)) return false;
((RefreshScrollTopInterface) fragment).triggerRefresh();
return true;
}
@Override
public Fragment getCurrentVisibleFragment() {
final int currentItem = mViewPager.getCurrentItem();
if (currentItem < 0 || currentItem >= mPagerAdapter.getCount()) return null;
return (Fragment) mPagerAdapter.instantiateItem(mViewPager, currentItem);
}
@Override
public boolean triggerRefresh(final int position) {
return false;
}
@Override
public boolean getSystemWindowsInsets(Rect insets) {
return false;
}
}

View File

@ -25,7 +25,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Rect;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@ -249,7 +248,7 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
if (actionBar == null) throw new NullPointerException();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(R.layout.actionbar_custom_view_message_user_picker);
actionBar.setCustomView(R.layout.layout_actionbar_message_user_picker);
final View actionBarView = actionBar.getCustomView();
mAccountSpinner = (Spinner) actionBarView.findViewById(R.id.account_spinner);
mEditUserQuery = (EditText) actionBarView.findViewById(R.id.user_query);

View File

@ -81,6 +81,7 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.meizu.flyme.reflect.StatusBarProxy;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
@ -213,6 +214,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
private int mActionBarShadowColor;
private int mUiColor;
private boolean mNameFirst;
private int mPreviousTabItemIsDark, mPreviousActionBarItemIsDark;
private final LoaderCallbacks<SingleResponse<Relationship>> mFriendshipLoaderCallbacks = new LoaderCallbacks<SingleResponse<Relationship>>() {
@ -402,7 +404,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
@Override
public boolean isScrollContent(float x, float y) {
final ViewPager v = mViewPager;
final View v = mViewPager;
final int[] location = new int[2];
v.getLocationInWindow(location);
return x >= location[0] && x <= location[0] + v.getWidth()
@ -892,6 +894,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
intent.putExtras(extras);
menu.removeGroup(MENU_GROUP_USER_EXTENSION);
Utils.addIntentToMenu(getActivity(), menu, intent, MENU_GROUP_USER_EXTENSION);
final HeaderDrawerLayout drawer = mHeaderDrawerLayout;
if (drawer != null) {
final int offset = drawer.getPaddingTop() - drawer.getHeaderTop();
updateScrollOffset(offset);
}
}
@Override
@ -1480,37 +1487,49 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
final int themeId = activity.getCurrentThemeResourceId();
if (ThemeUtils.isDarkTheme(themeId)) {
stackedTabColor = getResources().getColor(R.color.background_color_action_bar_dark);
final int contrastColor = TwidereColorUtils.getContrastYIQ(stackedTabColor, ThemeUtils.ACCENT_COLOR_THRESHOLD);
mPagerIndicator.setIconColor(contrastColor);
mPagerIndicator.setLabelColor(contrastColor);
mPagerIndicator.setStripColor(mUiColor);
} else if (drawable instanceof ColorDrawable) {
stackedTabColor = mUiColor;
final int tabColor = (Integer) sArgbEvaluator.evaluate(tabOutlineAlphaFactor, stackedTabColor, mCardBackgroundColor);
((ColorDrawable) drawable).setColor(tabColor);
final int contrastColor = TwidereColorUtils.getContrastYIQ(tabColor, ThemeUtils.ACCENT_COLOR_THRESHOLD);
mPagerIndicator.setIconColor(contrastColor);
mPagerIndicator.setLabelColor(contrastColor);
mPagerIndicator.setStripColor(contrastColor);
} else {
// This shouldn't happen, return
return;
stackedTabColor = mUiColor;
}
final int barColor = (Integer) sArgbEvaluator.evaluate(factor, mActionBarShadowColor, stackedTabColor);
final int itemColor = ThemeUtils.getContrastActionBarItemColor(activity, themeId, barColor);
final Toolbar actionBarView = activity.getActionBarToolbar();
if (actionBarView != null) {
actionBarView.setTitleTextColor(itemColor);
actionBarView.setSubtitleTextColor(itemColor);
ThemeUtils.setActionBarOverflowColor(actionBarView, itemColor);
ThemeUtils.wrapToolbarMenuIcon(ViewSupport.findViewByType(actionBarView, ActionMenuView.class), itemColor, itemColor);
final Drawable navigationIcon = actionBarView.getNavigationIcon();
if (navigationIcon != null) {
navigationIcon.setColorFilter(itemColor, Mode.SRC_ATOP);
final int tabColor = (Integer) sArgbEvaluator.evaluate(tabOutlineAlphaFactor, stackedTabColor, mCardBackgroundColor);
((ColorDrawable) drawable).setColor(tabColor);
final boolean tabItemIsDark = TwidereColorUtils.getYIQLuminance(tabColor) > ThemeUtils.ACCENT_COLOR_THRESHOLD;
if (mPreviousTabItemIsDark == 0 || (tabItemIsDark ? 1 : -1) != mPreviousTabItemIsDark) {
final int[] primaryColors = new int[2];
ThemeUtils.getDarkLightForegroundColors(activity, themeId, primaryColors);
final int tabContrastColor = primaryColors[tabItemIsDark ? 0 : 1];
mPagerIndicator.setIconColor(tabContrastColor);
mPagerIndicator.setLabelColor(tabContrastColor);
if (ThemeUtils.isDarkTheme(themeId)) {
mPagerIndicator.setStripColor(mUiColor);
} else {
mPagerIndicator.setStripColor(tabContrastColor);
}
actionBarView.setNavigationIcon(navigationIcon);
mPagerIndicator.updateAppearance();
}
mPagerIndicator.updateAppearance();
mPreviousTabItemIsDark = (tabItemIsDark ? 1 : -1);
final int barColor = (Integer) sArgbEvaluator.evaluate(factor, mActionBarShadowColor, stackedTabColor);
final boolean actionItemIsDark = TwidereColorUtils.getYIQLuminance(barColor) > ThemeUtils.ACCENT_COLOR_THRESHOLD;
if (mPreviousActionBarItemIsDark == 0 || (actionItemIsDark ? 1 : -1) != mPreviousActionBarItemIsDark) {
StatusBarProxy.setStatusBarDarkIcon(activity.getWindow(), actionItemIsDark);
final int itemColor = ThemeUtils.getContrastActionBarItemColor(activity, themeId, barColor);
final int titleColor = ThemeUtils.getContrastActionBarTitleColor(activity, themeId, barColor);
final Toolbar actionBarView = activity.getActionBarToolbar();
if (actionBarView != null) {
actionBarView.setTitleTextColor(titleColor);
actionBarView.setSubtitleTextColor(titleColor);
ThemeUtils.setActionBarOverflowColor(actionBarView, itemColor);
ThemeUtils.wrapToolbarMenuIcon(ViewSupport.findViewByType(actionBarView, ActionMenuView.class), itemColor, itemColor);
final Drawable navigationIcon = actionBarView.getNavigationIcon();
if (navigationIcon != null) {
navigationIcon.setColorFilter(itemColor, Mode.SRC_ATOP);
}
actionBarView.setNavigationIcon(navigationIcon);
}
}
mPreviousActionBarItemIsDark = actionItemIsDark ? 1 : -1;
}
updateTitleAlpha();
}

View File

@ -28,7 +28,7 @@ import org.mariotaku.twidere.model.ParcelableUserList;
import java.util.List;
public class UserListMembershipsListFragment extends ParcelableUserListsFragment {
public class UserListMembershipsFragment extends ParcelableUserListsFragment {
@Override
public Loader<List<ParcelableUserList>> onCreateUserListsLoader(final Context context,

View File

@ -1,115 +1,134 @@
/*
* Twidere - Twitter client for Android
*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.support;
import android.graphics.Rect;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.Loader;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.graphic.EmptyDrawable;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.TabPagerIndicator;
import org.mariotaku.twidere.adapter.AbsUserListsAdapter;
import org.mariotaku.twidere.loader.support.UserListsLoader;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.MenuUtils;
import org.mariotaku.twidere.util.Utils;
public class UserListsFragment extends BaseSupportFragment implements RefreshScrollTopInterface,
SupportFragmentCallback, SystemWindowsInsetsCallback {
import java.util.List;
private ViewPager mViewPager;
private TabPagerIndicator mPagerIndicator;
private View mPagerOverlay;
public class UserListsFragment extends ParcelableUserListsFragment {
private SupportTabsAdapter mPagerAdapter;
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
if (getActivity() == null || !isAdded() || isDetached()) return;
final String action = intent.getAction();
if (BROADCAST_USER_LIST_DELETED.equals(action)) {
final ParcelableUserList list = intent.getParcelableExtra(EXTRA_USER_LIST);
if (list != null) {
removeUserList(list.id);
}
}
}
};
@Override
public Loader<List<ParcelableUserList>> onCreateUserListsLoader(final Context context,
final Bundle args, final boolean fromUser) {
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
return new UserListsLoader(getActivity(), accountId, userId, screenName, true, getData());
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Bundle args = getArguments();
final FragmentActivity activity = getActivity();
mPagerAdapter = new SupportTabsAdapter(activity, getChildFragmentManager(), null, 1);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setOffscreenPageLimit(2);
mPagerIndicator.setViewPager(mViewPager);
mPagerIndicator.setTabDisplayOption(TabPagerIndicator.LABEL);
mPagerAdapter.addTab(UserListsListFragment.class, args, getString(R.string.follows), null, 0, null);
mPagerAdapter.addTab(UserListMembershipsListFragment.class, args, getString(R.string.belongs_to), 0, 1, null);
ThemeUtils.initPagerIndicatorAsActionBarTab(activity, mPagerIndicator, mPagerOverlay);
ThemeUtils.setCompatToolbarOverlay(activity, new EmptyDrawable());
ThemeUtils.setCompatContentViewOverlay(activity, new EmptyDrawable());
ThemeUtils.setWindowOverlayViewOverlay(activity, new EmptyDrawable());
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_content_pages, container, false);
setHasOptionsMenu(true);
}
@Override
public void onBaseViewCreated(final View view, final Bundle savedInstanceState) {
super.onBaseViewCreated(view, savedInstanceState);
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
mPagerIndicator = (TabPagerIndicator) view.findViewById(R.id.view_pager_tabs);
mPagerOverlay = view.findViewById(R.id.pager_window_overlay);
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.menu_user_lists_owned, menu);
}
@Override
public boolean scrollToStart() {
final Fragment fragment = getCurrentVisibleFragment();
if (!(fragment instanceof RefreshScrollTopInterface)) return false;
((RefreshScrollTopInterface) fragment).scrollToStart();
return true;
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.new_user_list: {
final DialogFragment f = new CreateUserListDialogFragment();
final Bundle args = new Bundle();
args.putLong(EXTRA_ACCOUNT_ID, getAccountId());
f.setArguments(args);
f.show(getFragmentManager(), null);
return true;
}
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean triggerRefresh() {
final Fragment fragment = getCurrentVisibleFragment();
if (!(fragment instanceof RefreshScrollTopInterface)) return false;
((RefreshScrollTopInterface) fragment).triggerRefresh();
return true;
public void onPrepareOptionsMenu(final Menu menu) {
final MenuItem item = menu.findItem(R.id.new_user_list);
if (item == null) return;
final long accountId = getAccountId(), userId = getUserId();
if (accountId == userId) {
MenuUtils.setMenuItemAvailability(menu, R.id.new_user_list, true);
} else {
MenuUtils.setMenuItemAvailability(menu, R.id.new_user_list, Utils.isMyAccount(getActivity(), getScreenName()));
}
}
private String getScreenName() {
return getArguments().getString(EXTRA_SCREEN_NAME);
}
private long getUserId() {
return getArguments().getLong(EXTRA_USER_ID);
}
@Override
public Fragment getCurrentVisibleFragment() {
final int currentItem = mViewPager.getCurrentItem();
if (currentItem < 0 || currentItem >= mPagerAdapter.getCount()) return null;
return (Fragment) mPagerAdapter.instantiateItem(mViewPager, currentItem);
public void onStart() {
super.onStart();
registerReceiver(mStatusReceiver, new IntentFilter(BROADCAST_USER_LIST_DELETED));
}
@Override
public boolean triggerRefresh(final int position) {
return false;
public void onStop() {
unregisterReceiver(mStatusReceiver);
super.onStop();
}
@Override
public boolean getSystemWindowsInsets(Rect insets) {
return false;
private void removeUserList(final long id) {
final AbsUserListsAdapter<List<ParcelableUserList>> adapter = getAdapter();
// final int listsIdx = adapter.findItemPosition(id);
// if (listsIdx >= 0) {
// adapter.removeAt(listsIdx);
// }
}
}

View File

@ -1,124 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.support;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.Loader;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.AbsUserListsAdapter;
import org.mariotaku.twidere.loader.support.UserListsLoader;
import org.mariotaku.twidere.model.ParcelableUserList;
import java.util.List;
public class UserListsListFragment extends ParcelableUserListsFragment {
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
if (getActivity() == null || !isAdded() || isDetached()) return;
final String action = intent.getAction();
if (BROADCAST_USER_LIST_DELETED.equals(action)) {
final ParcelableUserList list = intent.getParcelableExtra(EXTRA_USER_LIST);
if (list != null) {
removeUserList(list.id);
}
}
}
};
@Override
public Loader<List<ParcelableUserList>> onCreateUserListsLoader(final Context context,
final Bundle args, final boolean fromUser) {
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
final long userId = args.getLong(EXTRA_USER_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME);
return new UserListsLoader(getActivity(), accountId, userId, screenName, true, getData());
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.menu_user_lists_owned, menu);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.new_user_list: {
final DialogFragment f = new CreateUserListDialogFragment();
final Bundle args = new Bundle();
args.putLong(EXTRA_ACCOUNT_ID, getAccountId());
f.setArguments(args);
f.show(getFragmentManager(), null);
return true;
}
}
return super.onOptionsItemSelected(item);
}
@Override
public void onPrepareOptionsMenu(final Menu menu) {
// final MenuItem item = menu.findItem(R.id.new_user_list);
// if (item == null) return;
// final long account_id = getAccountId(), user_id = getUserId();
// final String screen_name = getAccountScreenName(getActivity(), account_id);
// item.setVisible(user_id == account_id || screen_name != null && screen_name.equalsIgnoreCase(getScreenName()));
}
public void onPullUpToRefresh() {
}
@Override
public void onStart() {
super.onStart();
registerReceiver(mStatusReceiver, new IntentFilter(BROADCAST_USER_LIST_DELETED));
}
@Override
public void onStop() {
unregisterReceiver(mStatusReceiver);
super.onStop();
}
private void removeUserList(final long id) {
final AbsUserListsAdapter<List<ParcelableUserList>> adapter = getAdapter();
// final int listsIdx = adapter.findItemPosition(id);
// if (listsIdx >= 0) {
// adapter.removeAt(listsIdx);
// }
}
}

View File

@ -273,7 +273,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_user_profile_editor, container, false);
return inflater.inflate(R.layout.fragment_user_profile_editor, container, false);
}
@Override

View File

@ -22,14 +22,12 @@ package org.mariotaku.twidere.loader.support;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.Handler;
import android.util.Log;
import android.util.Pair;
import com.bluelinelabs.logansquare.LoganSquare;
import org.mariotaku.jsonserializer.JSONFileIO;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.ParcelableActivity;
import org.mariotaku.twidere.util.Utils;
@ -56,8 +54,6 @@ public abstract class Twitter4JActivitiesLoader extends ParcelableActivitiesLoad
private final Context mContext;
private final long mAccountIds;
private final long mMaxId, mSinceId;
private final SQLiteDatabase mDatabase;
private final Handler mHandler;
private final Object[] mSavedStatusesFileArgs;
private Comparator<ParcelableActivity> mComparator;
@ -69,8 +65,6 @@ public abstract class Twitter4JActivitiesLoader extends ParcelableActivitiesLoad
mAccountIds = accountId;
mSinceId = sinceId;
mMaxId = maxId;
mDatabase = TwidereApplication.getInstance(context).getSQLiteDatabase();
mHandler = new Handler();
mSavedStatusesFileArgs = savedStatusesArgs;
}

View File

@ -56,7 +56,6 @@ public abstract class TwitterAPIStatusesLoader extends ParcelableStatusesLoader
private final Context mContext;
private final long mAccountId;
private final long mMaxId, mSinceId;
private final SQLiteDatabase mDatabase;
private final Object[] mSavedStatusesFileArgs;
private Comparator<ParcelableStatus> mComparator;
@ -68,7 +67,6 @@ public abstract class TwitterAPIStatusesLoader extends ParcelableStatusesLoader
mAccountId = accountId;
mMaxId = maxId;
mSinceId = sinceId;
mDatabase = TwidereApplication.getInstance(context).getSQLiteDatabase();
mSavedStatusesFileArgs = savedStatusesArgs;
}
@ -143,10 +141,11 @@ public abstract class TwitterAPIStatusesLoader extends ParcelableStatusesLoader
data.add(new ParcelableStatus(status, mAccountId, insertGap && isGapEnabled() && minIdx == i));
}
final SQLiteDatabase db = TwidereApplication.getInstance(context).getSQLiteDatabase();
final ParcelableStatus[] array = data.toArray(new ParcelableStatus[data.size()]);
for (int i = 0, size = array.length; i < size; i++) {
final ParcelableStatus status = array[i];
if (shouldFilterStatus(mDatabase, status) && !status.is_gap && i != size - 1) {
if (shouldFilterStatus(db, status) && !status.is_gap && i != size - 1) {
deleteStatus(data, status.id);
}
}

View File

@ -20,8 +20,10 @@
package org.mariotaku.twidere.util;
import android.os.SystemClock;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
@ -54,9 +56,11 @@ public class SimpleDrawerCallback implements DrawerCallback {
@Override
public boolean isScrollContent(float x, float y) {
final View v = mRecyclerView;
final int[] location = new int[2];
mRecyclerView.getLocationOnScreen(location);
return x >= location[0] && x <= location[0] && y >= location[1] && y <= location[1];
v.getLocationInWindow(location);
return x >= location[0] && x <= location[0] + v.getWidth()
&& y >= location[1] && y <= location[1] + v.getHeight();
}
@Override

View File

@ -28,54 +28,54 @@ import java.util.Locale;
public class StrictModeUtils {
public static final String LOGTAG = "Twidere.StrictMode";
public static final String CLASS_NAME = StrictModeUtils.class.getName();
public static final String LOGTAG = "Twidere.StrictMode";
public static final String CLASS_NAME = StrictModeUtils.class.getName();
public static void checkDiskIO() {
check("Disk IO");
}
public static void checkDiskIO() {
check("Disk IO");
}
public static void checkLengthyOperation() {
check("Lengthy operation");
}
public static void checkLengthyOperation() {
check("Lengthy operation");
}
public static void detectAllThreadPolicy() {
final ThreadPolicy.Builder threadPolicyBuilder = new ThreadPolicy.Builder();
threadPolicyBuilder.detectAll();
threadPolicyBuilder.penaltyLog();
StrictMode.setThreadPolicy(threadPolicyBuilder.build());
}
public static void detectAllThreadPolicy() {
final ThreadPolicy.Builder threadPolicyBuilder = new ThreadPolicy.Builder();
threadPolicyBuilder.detectAll();
threadPolicyBuilder.penaltyLog();
StrictMode.setThreadPolicy(threadPolicyBuilder.build());
}
public static void detectAllVmPolicy() {
final VmPolicy.Builder vmPolicyBuilder = new VmPolicy.Builder();
vmPolicyBuilder.detectAll();
vmPolicyBuilder.penaltyLog();
StrictMode.setVmPolicy(vmPolicyBuilder.build());
}
public static void detectAllVmPolicy() {
final VmPolicy.Builder vmPolicyBuilder = new VmPolicy.Builder();
vmPolicyBuilder.detectAll();
vmPolicyBuilder.penaltyLog();
StrictMode.setVmPolicy(vmPolicyBuilder.build());
}
private static void check(final String message) {
final Thread thread = Thread.currentThread();
if (thread == null || thread.getId() != 1) return;
final StackTraceElement[] framesArray = thread.getStackTrace();
private static void check(final String message) {
final Thread thread = Thread.currentThread();
if (thread.getId() != 1) return;
final StackTraceElement[] framesArray = thread.getStackTrace();
// look for the last stack frame from this class and then whatever is
// next is the caller we want to know about
int logCounter = -1;
for (final StackTraceElement stackFrame : framesArray) {
final String className = stackFrame.getClassName();
if (logCounter >= 0 && logCounter < 3) {
final String file = stackFrame.getFileName(), method = stackFrame.getMethodName();
final int line = stackFrame.getLineNumber();
final String nonEmptyFile = file != null ? file : "Unknown";
if (logCounter == 0) {
Log.w(LOGTAG, String.format(Locale.US, "%s on main thread:\n", message));
}
Log.w(LOGTAG, String.format(Locale.US, "\t at %s.%s(%s:%d)", className, method, nonEmptyFile, line));
if (++logCounter == 3) return;
} else if (CLASS_NAME.equals(className) && logCounter == -1) {
logCounter = 0;
}
}
}
// look for the last stack frame from this class and then whatever is
// next is the caller we want to know about
int logCounter = -1;
for (final StackTraceElement stackFrame : framesArray) {
final String className = stackFrame.getClassName();
if (logCounter >= 0 && logCounter < 3) {
final String file = stackFrame.getFileName(), method = stackFrame.getMethodName();
final int line = stackFrame.getLineNumber();
final String nonEmptyFile = file != null ? file : "Unknown";
if (logCounter == 0) {
Log.w(LOGTAG, String.format(Locale.US, "%s on main thread:\n", message));
}
Log.w(LOGTAG, String.format(Locale.US, "\t at %s.%s(%s:%d)", className, method, nonEmptyFile, line));
if (++logCounter == 3) return;
} else if (CLASS_NAME.equals(className) && logCounter == -1) {
logCounter = 0;
}
}
}
}

View File

@ -38,6 +38,7 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.app.AppCompatDelegateTrojan;
import android.support.v7.internal.app.ToolbarActionBar;
import android.support.v7.internal.app.WindowDecorActionBar;
import android.support.v7.internal.app.WindowDecorActionBar.ActionModeImpl;
import android.support.v7.internal.view.StandaloneActionMode;
@ -79,6 +80,7 @@ import org.mariotaku.twidere.text.ParagraphSpacingSpan;
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
import org.mariotaku.twidere.util.support.ViewSupport;
import org.mariotaku.twidere.view.TabPagerIndicator;
import org.mariotaku.twidere.view.TwidereToolbar;
import java.lang.reflect.Field;
@ -448,7 +450,7 @@ public class ThemeUtils implements Constants {
}
public static int getContrastActionBarItemColor(Context context, int theme, int color) {
if (isDarkTheme(theme) || TwidereColorUtils.getYIQLuminance(color) < ACCENT_COLOR_THRESHOLD) {
if (isDarkTheme(theme) || TwidereColorUtils.getYIQLuminance(color) <= ACCENT_COLOR_THRESHOLD) {
//return light text color
return context.getResources().getColor(R.color.action_icon_light);
}
@ -459,13 +461,13 @@ public class ThemeUtils implements Constants {
public static int getContrastActionBarTitleColor(Context context, int theme, int color) {
if (isDarkTheme(theme)) {
//return light text color
return getTextColorPrimary(context);
} else if (TwidereColorUtils.getYIQLuminance(color) < ACCENT_COLOR_THRESHOLD) {
return getColorFromAttribute(context, android.R.attr.colorForeground, Color.RED);
} else if (TwidereColorUtils.getYIQLuminance(color) <= ACCENT_COLOR_THRESHOLD) {
//return light text color
return getTextColorPrimaryInverse(context);
return getColorFromAttribute(context, android.R.attr.colorForegroundInverse, Color.RED);
} else {
//return dark text color
return getTextColorPrimary(context);
return getColorFromAttribute(context, android.R.attr.colorForeground, Color.RED);
}
}
@ -522,7 +524,7 @@ public class ThemeUtils implements Constants {
TwidereColorUtils.colorToYIQ(color, yiq);
final int y = yiq[0];
TwidereColorUtils.colorToYIQ(linkColor, yiq);
if (y < 32 && yiq[0] < ACCENT_COLOR_THRESHOLD) {
if (y < 32 && yiq[0] <= ACCENT_COLOR_THRESHOLD) {
return linkColor;
} else if (y > ACCENT_COLOR_THRESHOLD && yiq[0] > 32) {
return linkColor;
@ -574,6 +576,15 @@ public class ThemeUtils implements Constants {
}
}
public static int getColorFromAttribute(Context context, int attr, int def) {
final TypedValue outValue = new TypedValue();
if (!context.getTheme().resolveAttribute(attr, outValue, true))
return def;
if (outValue.type == TypedValue.TYPE_REFERENCE)
return context.getResources().getColor(attr);
return outValue.data;
}
public static int getTextAppearanceLarge(final Context context) {
// final Context wrapped = getThemedContext(context,
// getResources(context));
@ -1037,6 +1048,8 @@ public class ThemeUtils implements Constants {
actionBar.setSubtitle(actionBar.getSubtitle());
setActionBarTitleTextColor(window, titleColor);
setActionBarSubtitleTextColor(window, titleColor);
} else if (actionBar instanceof ToolbarActionBar) {
}
}
@ -1046,13 +1059,15 @@ public class ThemeUtils implements Constants {
drawable.setColorFilter(itemColor, Mode.SRC_ATOP);
}
toolbar.setNavigationIcon(drawable);
// Ensure title view created
toolbar.setTitleTextColor(titleColor);
toolbar.setSubtitleTextColor(titleColor);
}
public static void setActionBarOverflowColor(Toolbar toolbar, int itemColor) {
if (toolbar == null) return;
if (toolbar instanceof TwidereToolbar) {
((TwidereToolbar) toolbar).setItemColor(itemColor);
}
final ActionMenuView actionMenuView = ViewSupport.findViewByType(toolbar, ActionMenuView.class);
if (actionMenuView == null) return;
View overflowView = null;
@ -1068,6 +1083,21 @@ public class ThemeUtils implements Constants {
((ImageView) overflowView).setColorFilter(itemColor, Mode.SRC_ATOP);
}
public static void setActionBarMenuItemsColor(Toolbar toolbar, int itemColor) {
if (toolbar == null) return;
if (toolbar instanceof TwidereToolbar) {
((TwidereToolbar) toolbar).setItemColor(itemColor);
}
final ActionMenuView actionMenuView = ViewSupport.findViewByType(toolbar, ActionMenuView.class);
if (actionMenuView == null) return;
for (int i = 0, j = actionMenuView.getChildCount(); i < j; i++) {
final View child = actionMenuView.getChildAt(i);
if (child instanceof ActionMenuView.ActionMenuChildView && child instanceof ImageView) {
((ImageView) child).setColorFilter(itemColor, Mode.SRC_ATOP);
}
}
}
public static void setActionBarOverflowColor(ActionMenuPresenter presenter, int itemColor) {
if (presenter == null) return;
final View view = (View) Utils.findFieldOfTypes(presenter, ActionMenuPresenter.class,
@ -1100,10 +1130,10 @@ public class ThemeUtils implements Constants {
}
}
public static void setActionBarTitleTextColor(Window window, int itemColor) {
public static void setActionBarTitleTextColor(Window window, int titleColor) {
final View actionBarView = window.findViewById(android.support.v7.appcompat.R.id.action_bar);
if (actionBarView instanceof Toolbar) {
((Toolbar) actionBarView).setTitleTextColor(itemColor);
((Toolbar) actionBarView).setTitleTextColor(titleColor);
}
}

View File

@ -40,11 +40,13 @@ import android.view.InflateException;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.AppCompatPreferenceActivity;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.util.support.ViewSupport;
import org.mariotaku.twidere.view.ShapedImageView;
import org.mariotaku.twidere.view.TwidereToolbar;
import org.mariotaku.twidere.view.iface.IThemeAccentView;
@ -130,10 +132,12 @@ public class ThemedLayoutInflaterFactory implements LayoutInflaterFactory {
final boolean isActionBarContext = isActionBarContext(view.getContext(), getActionBarContext((Activity) activity));
final int themeResourceId = activity.getCurrentThemeResourceId();
final boolean isDarkTheme = ThemeUtils.isDarkTheme(themeResourceId);
final int backgroundColorApprox;
if (!isActionBarContext) {
accentColor = actionBarColor = activity.getCurrentThemeColor();
noTintColor = TwidereColorUtils.getContrastYIQ(accentColor, ThemeUtils.ACCENT_COLOR_THRESHOLD);
backgroundTintColor = accentColor;
backgroundColorApprox = isDarkTheme ? Color.BLACK : Color.WHITE;
isColorTint = true;
} else if (isDarkTheme) {
// View context is derived from ActionBar but is currently dark theme, so we should show
@ -142,6 +146,7 @@ public class ThemedLayoutInflaterFactory implements LayoutInflaterFactory {
noTintColor = Color.WHITE;
accentColor = activity.getCurrentThemeColor();
backgroundTintColor = noTintColor;
backgroundColorApprox = Color.BLACK;
isColorTint = true;
} else {
// View context is derived from ActionBar and it's light theme, so we use contrast color
@ -149,14 +154,20 @@ public class ThemedLayoutInflaterFactory implements LayoutInflaterFactory {
accentColor = TwidereColorUtils.getContrastYIQ(actionBarColor, ThemeUtils.ACCENT_COLOR_THRESHOLD);
noTintColor = TwidereColorUtils.getContrastYIQ(accentColor, ThemeUtils.ACCENT_COLOR_THRESHOLD);
backgroundTintColor = accentColor;
backgroundColorApprox = Color.WHITE;
isColorTint = false;
}
if (view instanceof TextView) {
final TextView textView = (TextView) view;
textView.setLinkTextColor(accentColor);
if (Math.abs(TwidereColorUtils.getYIQContrast(backgroundColorApprox, accentColor)) > 64) {
textView.setLinkTextColor(accentColor);
}
}
if (view instanceof IThemeAccentView) {
((IThemeAccentView) view).setAccentTintColor(ColorStateList.valueOf(accentColor));
if (Math.abs(TwidereColorUtils.getYIQContrast(backgroundColorApprox, accentColor)) > 64) {
((IThemeAccentView) view).setAccentTintColor(ColorStateList.valueOf(accentColor));
}
} else if (view instanceof IThemeBackgroundTintView) {
((IThemeBackgroundTintView) view).setBackgroundTintColor(ColorStateList.valueOf(backgroundTintColor));
} else if (view instanceof TintableBackgroundView) {
@ -168,6 +179,9 @@ public class ThemedLayoutInflaterFactory implements LayoutInflaterFactory {
((TwidereToolbar) view).setItemColor(itemColor);
} else if (view instanceof EditText) {
ViewCompat.setBackgroundTintList(view, ColorStateList.valueOf(accentColor));
} else if (view instanceof ProgressBar) {
ViewSupport.setProgressTintList((ProgressBar) view, ColorStateList.valueOf(accentColor));
ViewSupport.setProgressBackgroundTintList((ProgressBar) view, ColorStateList.valueOf(accentColor));
}
}

View File

@ -123,4 +123,8 @@ public class TwidereColorUtils {
final int yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
return (yiq >= threshold) ? colorDark : colorLight;
}
public static int getYIQContrast(int color1, int color2) {
return getYIQLuminance(color1) - getYIQLuminance(color2);
}
}

View File

@ -144,6 +144,7 @@ import org.mariotaku.twidere.fragment.support.DestroyStatusDialogFragment;
import org.mariotaku.twidere.fragment.support.DraftsFragment;
import org.mariotaku.twidere.fragment.support.FiltersFragment;
import org.mariotaku.twidere.fragment.support.IncomingFriendshipsFragment;
import org.mariotaku.twidere.fragment.support.ListsFragment;
import org.mariotaku.twidere.fragment.support.MessagesConversationFragment;
import org.mariotaku.twidere.fragment.support.MutesUsersListFragment;
import org.mariotaku.twidere.fragment.support.SavedSearchesListFragment;
@ -163,10 +164,9 @@ import org.mariotaku.twidere.fragment.support.UserFragment;
import org.mariotaku.twidere.fragment.support.UserFriendsFragment;
import org.mariotaku.twidere.fragment.support.UserListFragment;
import org.mariotaku.twidere.fragment.support.UserListMembersFragment;
import org.mariotaku.twidere.fragment.support.UserListMembershipsListFragment;
import org.mariotaku.twidere.fragment.support.UserListMembershipsFragment;
import org.mariotaku.twidere.fragment.support.UserListSubscribersFragment;
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserListsFragment;
import org.mariotaku.twidere.fragment.support.UserMediaTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserMentionsFragment;
import org.mariotaku.twidere.fragment.support.UserProfileEditorFragment;
@ -812,7 +812,7 @@ public final class Utils implements Constants, TwitterConstants {
break;
}
case LINK_ID_USER_LIST_MEMBERSHIPS: {
fragment = new UserListMembershipsListFragment();
fragment = new UserListMembershipsFragment();
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
final String paramUserId = uri.getQueryParameter(QUERY_PARAM_USER_ID);
if (!args.containsKey(EXTRA_SCREEN_NAME)) {
@ -925,7 +925,7 @@ public final class Utils implements Constants, TwitterConstants {
break;
}
case LINK_ID_USER_LISTS: {
fragment = new UserListsFragment();
fragment = new ListsFragment();
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
final String paramUserId = uri.getQueryParameter(QUERY_PARAM_USER_ID);
if (!args.containsKey(EXTRA_SCREEN_NAME)) {

View File

@ -67,7 +67,6 @@ public class ShapedImageView extends ImageView {
@ShapeStyle
public static final int SHAPE_RECTANGLE = 0x2;
private static final int SHADOW_START_COLOR = 0x37000000;
private static final boolean USE_OUTLINE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
private static final boolean OUTLINE_DRAW = false;
private final Matrix mMatrix;
private final RectF mSource;
@ -128,7 +127,7 @@ public class ShapedImageView extends ImageView {
setCornerRadius(a.getDimension(R.styleable.ShapedImageView_sivCornerRadius, 0));
setCornerRadiusRatio(a.getFraction(R.styleable.ShapedImageView_sivCornerRadiusRatio, 1, 1, -1));
if (USE_OUTLINE) {
if (useOutline()) {
if (a.hasValue(R.styleable.ShapedImageView_sivElevation)) {
ViewCompat.setElevation(this,
a.getDimensionPixelSize(R.styleable.ShapedImageView_sivElevation, 0));
@ -139,9 +138,7 @@ public class ShapedImageView extends ImageView {
setBackgroundColor(a.getColor(R.styleable.ShapedImageView_sivBackgroundColor, 0));
a.recycle();
if (USE_OUTLINE) {
initOutlineProvider();
}
initOutlineProvider();
}
/**
@ -426,6 +423,7 @@ public class ShapedImageView extends ImageView {
}
private void initOutlineProvider() {
if (!useOutline()) return;
ViewSupport.setClipToOutline(this, true);
ViewSupport.setOutlineProvider(this, new CircularOutlineProvider());
}
@ -466,7 +464,7 @@ public class ShapedImageView extends ImageView {
}
private void updateShadowBitmap() {
if (USE_OUTLINE) return;
if (useOutline()) return;
final int width = getWidth(), height = getHeight();
if (width <= 0 || height <= 0) return;
final int contentLeft = getPaddingLeft(), contentTop = getPaddingTop(),
@ -497,6 +495,10 @@ public class ShapedImageView extends ImageView {
invalidate();
}
private boolean useOutline() {
return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP && !isInEditMode();
}
@IntDef({SHAPE_CIRCLE, SHAPE_RECTANGLE})
@Retention(RetentionPolicy.SOURCE)
public @interface ShapeStyle {
@ -505,9 +507,10 @@ public class ShapedImageView extends ImageView {
private static class CircularOutlineProvider extends ViewOutlineProviderCompat {
@Override
public void getOutline(View view, OutlineCompat outline) {
final int viewWidth = view.getWidth(), viewHeight = view.getHeight();
final int contentLeft = view.getPaddingLeft(), contentTop = view.getPaddingTop(),
contentRight = view.getWidth() - view.getPaddingRight(),
contentBottom = view.getHeight() - view.getPaddingBottom();
contentRight = viewWidth - view.getPaddingRight(),
contentBottom = viewHeight - view.getPaddingBottom();
final ShapedImageView imageView = (ShapedImageView) view;
if (imageView.getStyle() == SHAPE_CIRCLE) {
final int contentWidth = contentRight - contentLeft,

View File

@ -1,152 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.MathUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.iface.TintedStatusLayout;
/**
* Created by mariotaku on 14/11/26.
*/
public class TintedStatusRelativeLayout extends ExtendedRelativeLayout implements TintedStatusLayout {
private final Paint mBlackPaint, mShadowPaint, mColorPaint;
private boolean mSetPadding;
private int mStatusBarHeight;
private float mFactor;
private int mColorAlpha, mShadowAlpha;
private boolean mDrawShadow, mDrawColor;
private Rect mSystemWindowsInsets;
public TintedStatusRelativeLayout(Context context) {
this(context, null);
}
public TintedStatusRelativeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TintedStatusRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TintedStatusLayout);
setSetPaddingEnabled(a.getBoolean(R.styleable.TintedStatusLayout_setPadding, false));
a.recycle();
mBlackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBlackPaint.setColor(Color.BLACK);
mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mSystemWindowsInsets = new Rect();
setWillNotDraw(false);
setFactor(1);
}
@Override
public void setColor(int color) {
setColor(color, Color.alpha(color));
}
@Override
public void setColor(int color, int alpha) {
mColorPaint.setColor(color);
mColorAlpha = alpha;
updateAlpha();
}
@Override
public void setDrawColor(boolean color) {
mDrawColor = color;
invalidate();
}
@Override
public void setDrawShadow(boolean shadow) {
mDrawShadow = shadow;
invalidate();
}
@Override
public void setFactor(float f) {
mFactor = f;
updateAlpha();
}
@Override
public void setShadowColor(int color) {
mShadowPaint.setColor(color);
mShadowAlpha = Color.alpha(color);
updateAlpha();
}
@Override
public void setSetPaddingEnabled(boolean enabled) {
mSetPadding = enabled;
}
public void setStatusBarHeight(int height) {
mStatusBarHeight = height;
invalidate();
}
@Override
public void getSystemWindowsInsets(Rect insets) {
insets.set(mSystemWindowsInsets);
}
@Override
protected void dispatchDraw(@NonNull Canvas canvas) {
super.dispatchDraw(canvas);
if (mDrawShadow) {
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mShadowPaint);
} else if (mDrawColor) {
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mBlackPaint);
}
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mDrawColor ? mColorPaint : mBlackPaint);
}
@Override
protected boolean fitSystemWindows(@NonNull Rect insets) {
setStatusBarHeight(Utils.getInsetsTopWithoutActionBarHeight(getContext(), insets.top));
if (mSetPadding) {
setPadding(insets.left, insets.top, insets.right, insets.bottom);
}
mSystemWindowsInsets.set(insets);
return super.fitSystemWindows(insets);
}
private void updateAlpha() {
final float f = mFactor;
mShadowPaint.setAlpha(Math.round(mShadowAlpha * MathUtils.clamp(1 - f, 0, 1)));
mColorPaint.setAlpha(Math.round(0xFF * MathUtils.clamp(f, 0, 1)));
invalidate();
}
}

View File

@ -26,26 +26,27 @@ import android.util.AttributeSet;
import com.rengwuxian.materialedittext.MaterialEditText;
import org.mariotaku.twidere.view.iface.IThemeAccentView;
import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView;
/**
* Created by mariotaku on 15/4/29.
*/
public class ThemedAccentMaterialEditText extends MaterialEditText implements IThemeAccentView {
public ThemedAccentMaterialEditText(Context context) {
public class ThemedBackgroundTintMaterialEditText extends MaterialEditText implements IThemeBackgroundTintView {
public ThemedBackgroundTintMaterialEditText(Context context) {
super(context);
}
public ThemedAccentMaterialEditText(Context context, AttributeSet attrs) {
public ThemedBackgroundTintMaterialEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ThemedAccentMaterialEditText(Context context, AttributeSet attrs, int style) {
public ThemedBackgroundTintMaterialEditText(Context context, AttributeSet attrs, int style) {
super(context, attrs, style);
}
@Override
public void setAccentTintColor(@NonNull ColorStateList color) {
public void setBackgroundTintColor(@NonNull ColorStateList color) {
setPrimaryColor(color.getDefaultColor());
}
}

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<org.mariotaku.twidere.view.TintedStatusFrameLayout
android:id="@+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:setPadding="true"/>

View File

@ -1,5 +1,4 @@
<?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>
@ -31,8 +30,7 @@
android:id="@+id/compose_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:animateLayoutChanges="true">
android:layout_weight="1">
<org.mariotaku.dynamicgridview.DynamicGridView
android:id="@+id/media_thumbnail_preview"
@ -45,7 +43,7 @@
android:alpha="0.2"
android:numColumns="@integer/grid_column_image_preview"
android:stretchMode="columnWidth"
tools:listitem="@layout/grid_item_image_preview"/>
tools:listitem="@layout/grid_item_image_preview" />
<LinearLayout
android:id="@+id/edit_text_container"
@ -64,7 +62,7 @@
android:hint="@string/status_hint"
android:minLines="6"
android:padding="@dimen/element_spacing_normal"
android:scrollbars="vertical"/>
android:scrollbars="vertical" />
<LinearLayout
android:id="@+id/location_container"
@ -84,13 +82,13 @@
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginRight="@dimen/element_spacing_normal"
android:color="?android:textColorSecondary"
android:src="@drawable/ic_action_location"/>
android:src="@drawable/ic_action_location" />
<TextView
android:id="@+id/location_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/element_spacing_normal"/>
android:layout_marginRight="@dimen/element_spacing_normal" />
</LinearLayout>
@ -111,7 +109,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
android:overScrollMode="never"/>
android:overScrollMode="never" />
</FrameLayout>
</RelativeLayout>
@ -126,6 +124,6 @@
android:orientation="vertical"
android:showDividers="beginning">
<include layout="@layout/activity_compose_bottombar"/>
<include layout="@layout/activity_compose_bottombar" />
</LinearLayout>
</LinearLayout>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<org.mariotaku.twidere.view.TintedStatusFrameLayout
android:id="@+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:setPadding="true">
<include layout="@layout/layout_content_pages_common"/>
</org.mariotaku.twidere.view.TintedStatusFrameLayout>

View File

@ -27,20 +27,31 @@
<org.mariotaku.twidere.view.SquareShapedImageView
android:id="@android:id/icon"
style="?profileImageStyle"
style="?profileImageStyleLarge"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:sivBorder="true"
app:sivBorderWidth="@dimen/line_width_compose_account_profile_image" />
app:sivBorderWidth="@dimen/line_width_compose_account_profile_image"
app:sivElevation="@dimen/elevation_card" />
<TextView
android:id="@android:id/text1"
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
tool:text="Name" />
android:layout_marginLeft="@dimen/element_spacing_msmall"
app:cardBackgroundColor="?android:colorBackgroundCacheHint"
app:cardElevation="@dimen/elevation_card"
app:contentPadding="@dimen/element_spacing_small">
<TextView
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
tool:text="Name" />
</android.support.v7.widget.CardView>
</LinearLayout>

View File

@ -23,7 +23,7 @@
android:layout_height="match_parent"
android:padding="8dp">
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
<org.mariotaku.twidere.view.themed.ThemedBackgroundTintMaterialEditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -37,7 +37,7 @@
app:met_floatingLabelText="@string/name"
app:met_maxCharacters="20" />
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
<org.mariotaku.twidere.view.themed.ThemedBackgroundTintMaterialEditText
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<org.mariotaku.twidere.view.HeaderDrawerLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentLayout="@layout/fragment_content_pages"
app:headerLayout="@layout/header_user_list"/>
<include layout="@layout/layout_content_fragment_common"/>
</FrameLayout>

View File

@ -93,6 +93,7 @@
android:id="@+id/profile_image_camera"
style="?android:borderlessButtonStyle"
android:layout_width="0dp"
android:background="?selectableItemBackground"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_action_camera"
@ -106,6 +107,7 @@
android:id="@+id/profile_image_gallery"
style="?android:borderlessButtonStyle"
android:layout_width="0dp"
android:background="?selectableItemBackground"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_action_gallery"
@ -148,7 +150,7 @@
android:paddingTop="@dimen/element_spacing_normal"
android:text="@string/profile_banner"
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold" />
@ -167,6 +169,7 @@
android:drawableLeft="@drawable/ic_action_gallery"
android:paddingBottom="0dp"
android:paddingLeft="@dimen/element_spacing_normal"
android:background="?selectableItemBackground"
android:paddingRight="@dimen/element_spacing_normal"
android:paddingTop="0dp"
android:text="@string/gallery" />
@ -174,6 +177,7 @@
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/profile_banner_remove"
style="?android:borderlessButtonStyle"
android:background="?selectableItemBackground"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
@ -208,7 +212,7 @@
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal">
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
<org.mariotaku.twidere.view.themed.ThemedBackgroundTintMaterialEditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -219,7 +223,7 @@
app:met_floatingLabelText="@string/name"
app:met_maxCharacters="20" />
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
<org.mariotaku.twidere.view.themed.ThemedBackgroundTintMaterialEditText
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -231,7 +235,7 @@
app:met_floatingLabelText="@string/description"
app:met_maxCharacters="160" />
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
<org.mariotaku.twidere.view.themed.ThemedBackgroundTintMaterialEditText
android:id="@+id/location"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -242,7 +246,7 @@
app:met_floatingLabelText="@string/location"
app:met_maxCharacters="30" />
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
<org.mariotaku.twidere.view.themed.ThemedBackgroundTintMaterialEditText
android:id="@+id/url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -293,7 +297,7 @@
android:layout_weight="1"
android:text="@string/profile_link_color_main_color"
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold" />
@ -321,7 +325,7 @@
android:layout_weight="1"
android:text="@string/profile_background_color"
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold" />
@ -341,11 +345,7 @@
android:visibility="visible"
tools:visibility="gone">
<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<include layout="@layout/layout_progress_wheel_medium" />
</FrameLayout>
</FrameLayout>

View File

@ -16,6 +16,7 @@
<item name="sivElevation">@dimen/elevation_card</item>
<item name="sivBorderWidth">2dp</item>
<item name="sivBackgroundColor">?android:colorBackground</item>
<item name="sivShape">circle</item>
</style>
<style name="Widget.Light.ProfileImage.Large">
@ -23,6 +24,7 @@
<item name="sivElevation">@dimen/elevation_card</item>
<item name="sivBorderWidth">2dp</item>
<item name="sivBackgroundColor">?android:colorBackground</item>
<item name="sivShape">circle</item>
</style>
<style name="Widget.ProfileType" parent="Widget.Base">

View File

@ -31,6 +31,7 @@
<item name="sivBorderWidth">1dp</item>
<item name="sivCornerRadiusRatio">10%p</item>
<item name="sivBackgroundColor">?android:colorBackground</item>
<item name="sivShape">circle</item>
</style>
<style name="Widget.Light.ProfileImage" parent="Widget.Base">
@ -38,6 +39,7 @@
<item name="sivBorderWidth">1dp</item>
<item name="sivCornerRadiusRatio">10%p</item>
<item name="sivBackgroundColor">?android:colorBackground</item>
<item name="sivShape">circle</item>
</style>
<style name="Widget.ProfileImage.Large">
@ -48,6 +50,7 @@
<item name="sivElevation">@dimen/elevation_card</item>
<item name="sivBorderWidth">2dp</item>
<item name="sivBackgroundColor">?android:colorBackground</item>
<item name="sivShape">circle</item>
</style>
<style name="Widget.Light.ProfileImage.Large">
@ -58,6 +61,7 @@
<item name="sivElevation">@dimen/elevation_card</item>
<item name="sivBorderWidth">2dp</item>
<item name="sivBackgroundColor">?android:colorBackground</item>
<item name="sivShape">circle</item>
</style>
<style name="Widget.ProfileType" parent="Widget.Base">