Skip to content

Commit

Permalink
feature: 新增自定义首页顶栏Tab
Browse files Browse the repository at this point in the history
  • Loading branch information
CLOUDERHEM committed Jan 31, 2024
1 parent fb3de68 commit d04737e
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 6 deletions.
4 changes: 3 additions & 1 deletion app/src/main/java/com/shatyuka/zhiliao/Hooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.shatyuka.zhiliao.hooks.ColorMode;
import com.shatyuka.zhiliao.hooks.CommentAd;
import com.shatyuka.zhiliao.hooks.CustomFilter;
import com.shatyuka.zhiliao.hooks.CustomTabFilter;
import com.shatyuka.zhiliao.hooks.ExternLink;
import com.shatyuka.zhiliao.hooks.FeedAd;
import com.shatyuka.zhiliao.hooks.FeedTopHotBanner;
Expand Down Expand Up @@ -63,7 +64,8 @@ public class Hooks {
new Cleaner(),
new FeedTopHotBanner(),
new HeadZoneBanner(),
new MineHybridView()
new MineHybridView(),
new CustomTabFilter(),
};

public static void init(final ClassLoader classLoader) {
Expand Down
103 changes: 103 additions & 0 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/CustomTabFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.shatyuka.zhiliao.hooks;

import com.shatyuka.zhiliao.Helper;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;


public class CustomTabFilter implements IHook {

static Class<?> mainPageFragment;

static Field customTabInfoList;

static Field tabType;

@Override
public String getName() {
return "自定义首页顶栏Tab";
}

@Override
public void init(ClassLoader classLoader) throws Throwable {
mainPageFragment = classLoader.loadClass("com.zhihu.android.app.feed.explore.view.MainPageFragment");

customTabInfoList = Arrays.stream(mainPageFragment.getDeclaredFields())
.filter(field -> field.getType() == List.class).findFirst().get();
customTabInfoList.setAccessible(true);

tabType = classLoader.loadClass("com.zhihu.android.api.model.CustomTabInfo").getDeclaredField("tab_type");
tabType.setAccessible(true);
}

@Override
public void hook() throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false)) {
XposedBridge.hookAllMethods(mainPageFragment, "onCreate", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {

List<Object> tabList = (List<Object>) customTabInfoList.get(param.thisObject);

String tabFilter = Helper.prefs.getString("edit_tabfilter", "");
if (tabFilter.isEmpty()) {
Helper.prefs.edit().putString("edit_tabfilter", encodePattern(tabList)).apply();
} else {
List<Object> postProcessTabList = postProcessTabList(tabList, decodePattern(tabFilter));
customTabInfoList.set(param.thisObject, postProcessTabList);
}
}

});
}
}

private String encodePattern(List<Object> tabList) {
if (tabList == null || tabList.isEmpty()) {
return null;
}
return tabList.stream().map(o -> {
try {
return (String) tabType.get(o);
} catch (IllegalAccessException e) {
return null;
}
}).filter(s -> s != null && !s.isEmpty())
.collect(Collectors.joining("|"));
}

private List<String> decodePattern(String pattern) {
return Arrays.stream(pattern.split("\\|"))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());
}

private List<Object> postProcessTabList(List<Object> tabList, List<String> typeFilterList) {
if (tabList == null || tabList.isEmpty()) {
return tabList;
}

Map<String, Object> typeTabMap = tabList.stream()
.collect(Collectors.toMap(tab -> {
try {
return (String) tabType.get(tab);
} catch (IllegalAccessException ignore) {
return null;
}
}, tab -> tab));

return typeFilterList.stream()
.map(typeTabMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}
23 changes: 18 additions & 5 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/ZhihuPreference.java
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
Object switch_autoclean = findPreference.invoke(thisObject, "switch_autoclean");
Object switch_feedtophot = findPreference.invoke(thisObject, "switch_feedtophot");
Object switch_minehybrid = findPreference.invoke(thisObject, "switch_minehybrid");
Object edit_tabfilter = findPreference.invoke(thisObject, "edit_tabfilter");

setOnPreferenceChangeListener.invoke(findPreference.invoke(thisObject, "accept_eula"), thisObject);
setOnPreferenceClickListener.invoke(switch_externlink, thisObject);
Expand Down Expand Up @@ -430,6 +431,7 @@ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
setOnPreferenceClickListener.invoke(preference_donate, thisObject);
setOnPreferenceClickListener.invoke(switch_feedtophot, thisObject);
setOnPreferenceClickListener.invoke(switch_minehybrid, thisObject);
setOnPreferenceChangeListener.invoke(edit_tabfilter, thisObject);

String real_version = null;
try {
Expand Down Expand Up @@ -517,6 +519,7 @@ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
setIcon.invoke(preference_donate, Helper.modRes.getDrawable(R.drawable.ic_monetization));
setIcon.invoke(findPreference.invoke(thisObject, "switch_feedtophot"), Helper.modRes.getDrawable(R.drawable.ic_whatshot));
setIcon.invoke(findPreference.invoke(thisObject, "switch_minehybrid"), Helper.modRes.getDrawable(R.drawable.ic_viewcard));
setIcon.invoke(findPreference.invoke(thisObject, "edit_tabfilter"), Helper.modRes.getDrawable(R.drawable.ic_filter));

if (Helper.prefs.getBoolean("accept_eula", false)) {
Object category_eula = findPreference.invoke(thisObject, "category_eula");
Expand Down Expand Up @@ -620,12 +623,22 @@ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.hookMethod(Helper.getMethodByParameterTypes(DebugFragment, Preference, Object.class), new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
if ((boolean) param.args[1]) {
Object switch_main = findPreference.invoke(param.thisObject, "switch_mainswitch");
setChecked.invoke(switch_main, true);
Object category_eula = findPreference.invoke(param.thisObject, "category_eula");
setVisible.invoke(category_eula, false);
if (param.args[0].getClass() == SwitchPreference) {
if (param.args[1] instanceof Boolean) {
if ((boolean) param.args[1]) {
Object switch_main = findPreference.invoke(param.thisObject, "switch_mainswitch");
setChecked.invoke(switch_main, true);
Object category_eula = findPreference.invoke(param.thisObject, "category_eula");
setVisible.invoke(category_eula, false);
}
}
} else if (param.args[0].getClass() == EditTextPreference) {
String key = (String) getKey.invoke(param.args[0]);
if ("edit_tabfilter".equals(key)) {
Helper.toast("重启知乎生效", Toast.LENGTH_SHORT);
}
}

return true;
}
});
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_filter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#808080"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M10.83,8H21V6H8.83L10.83,8zM15.83,13H18v-2h-4.17L15.83,13zM14,16.83V18h-4v-2h3.17l-3,-3H6v-2h2.17l-3,-3H3V6h0.17L1.39,4.22l1.41,-1.41l18.38,18.38l-1.41,1.41L14,16.83z"/>
</vector>
6 changes: 6 additions & 0 deletions app/src/main/res/xml/preferences_zhihu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@
android:key="switch_minehybrid"
android:title="隐藏混合卡片"
android:summary="隐藏「我的」底部混合卡片"/>
<EditTextPreference
android:defaultValue=""
android:dependency="switch_mainswitch"
android:key="edit_tabfilter"
android:title="自定义首页顶栏Tab"
android:summary="使用 | 隔开, 留空则忽略"/>
</PreferenceCategory>
<PreferenceCategory android:title="左右划" android:key="category_swap_answers">
<com.zhihu.android.app.ui.widget.SwitchPreference
Expand Down

0 comments on commit d04737e

Please sign in to comment.