Skip to content

Commit

Permalink
Feature && Bug fixing (#112)
Browse files Browse the repository at this point in the history
* 新增隐藏推荐页顶部热门推荐

* fix: 隐藏导航栏失效

* fix: 知了设置不显示

* feature: 新增隐藏热榜顶部置顶功能

* fix: 隐藏会员卡片

* feature: 隐藏「我的」底部混合卡片

* refactor: item获取方式

* fix: 卡片类别偶尔不对齐

* feature: 去除关注按钮

* refactor: 显示卡片类别

* feature: 去除webview时关注按钮
  • Loading branch information
CLOUDERHEM committed Mar 9, 2024
1 parent 0994cc4 commit aef8941
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 74 deletions.
9 changes: 9 additions & 0 deletions app/src/main/java/com/shatyuka/zhiliao/Hooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
import com.shatyuka.zhiliao.hooks.CustomFilter;
import com.shatyuka.zhiliao.hooks.ExternLink;
import com.shatyuka.zhiliao.hooks.FeedAd;
import com.shatyuka.zhiliao.hooks.FeedTopHotBanner;
import com.shatyuka.zhiliao.hooks.FollowButton;
import com.shatyuka.zhiliao.hooks.HeadZoneBanner;
import com.shatyuka.zhiliao.hooks.Horizontal;
import com.shatyuka.zhiliao.hooks.HotBanner;
import com.shatyuka.zhiliao.hooks.IHook;
import com.shatyuka.zhiliao.hooks.LaunchAd;
import com.shatyuka.zhiliao.hooks.LiveButton;
import com.shatyuka.zhiliao.hooks.MineHybridView;
import com.shatyuka.zhiliao.hooks.NavButton;
import com.shatyuka.zhiliao.hooks.NavRes;
import com.shatyuka.zhiliao.hooks.NextAnswer;
Expand Down Expand Up @@ -58,6 +62,10 @@ public class Hooks {
new NavRes(),
new WebView(),
new Cleaner(),
new FeedTopHotBanner(),
new HeadZoneBanner(),
new MineHybridView(),
new FollowButton()
};

public static void init(final ClassLoader classLoader) {
Expand All @@ -68,6 +76,7 @@ public static void init(final ClassLoader classLoader) {
} catch (Throwable e) {
Helper.toast(hook.getName() + "功能加载失败,可能不支持当前版本知乎: " + Helper.packageInfo.versionName, Toast.LENGTH_LONG);
XposedBridge.log("[Zhiliao] " + e);
XposedBridge.log(e);
}
}
}
Expand Down
32 changes: 32 additions & 0 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/FeedTopHotBanner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.shatyuka.zhiliao.hooks;

import com.shatyuka.zhiliao.Helper;

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

public class FeedTopHotBanner implements IHook {
static Class<?> feedTopHotAutoJacksonDeserializer;

@Override
public String getName() {
return "隐藏推荐页置顶热门";
}

@Override
public void init(ClassLoader classLoader) throws Throwable {
feedTopHotAutoJacksonDeserializer = classLoader.loadClass("com.zhihu.android.api.model.FeedTopHotAutoJacksonDeserializer");
}

@Override
public void hook() throws Throwable {
XposedBridge.hookAllMethods(feedTopHotAutoJacksonDeserializer, "deserialize", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_feedtophot", false)) {
param.setResult(null);
}
}
});
}
}
82 changes: 82 additions & 0 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/FollowButton.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.shatyuka.zhiliao.hooks;

import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.shatyuka.zhiliao.Helper;

import java.lang.reflect.Field;
import java.util.Arrays;

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

/**
* 卡片视图去除关注按钮
* todo: 整合web去除关注
*/
public class FollowButton implements IHook {
static Class<?> followWithAvatarView;

static Class<?> bottomReactionView;

static Class<?> followPeopleButton;

static Class<?> zHAuthorInfoView;

static Field followWithAvatarViewField;

static Field followPeopleButtonField;

@Override
public String getName() {
return "去关注按钮";
}

@Override
public void init(ClassLoader classLoader) throws Throwable {
followWithAvatarView = classLoader.loadClass("com.zhihu.android.unify_interactive.view.follow.FollowWithAvatarView");
bottomReactionView = classLoader.loadClass("com.zhihu.android.mixshortcontainer.function.mixup.view.BottomReactionView");

followPeopleButton = classLoader.loadClass("com.zhihu.android.unify_interactive.view.follow.FollowPeopleButton");
zHAuthorInfoView = classLoader.loadClass("com.zhihu.android.mixshortcontainer.function.mixup.author.ZHAuthorInfoView");

followWithAvatarViewField = findFieldByType(bottomReactionView, followWithAvatarView);
followPeopleButtonField = findFieldByType(zHAuthorInfoView, followPeopleButton);
}

@Override
public void hook() throws Throwable {

XposedBridge.hookAllMethods(bottomReactionView, "setData", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_subscribe", false)) {
// 去除底部关注(带头像)
FrameLayout followWithAvatarViewInstance = (FrameLayout) followWithAvatarViewField.get(param.thisObject);
followWithAvatarViewInstance.setVisibility(View.GONE);
}
}
});

XposedBridge.hookAllMethods(zHAuthorInfoView, "setData", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_subscribe", false)) {
// 去除顶部关注
ViewGroup followPeopleButtonFieldInstance = (ViewGroup) followPeopleButtonField.get(param.thisObject);
followPeopleButtonFieldInstance.setVisibility(View.GONE);
}
}
});
}

private Field findFieldByType(Class<?> clazz, Class<?> type) {
Field field = Arrays.stream(clazz.getDeclaredFields())
.filter(f -> f.getType() == type).findFirst().get();

field.setAccessible(true);
return field;
}
}
40 changes: 40 additions & 0 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/HeadZoneBanner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.shatyuka.zhiliao.hooks;

import com.shatyuka.zhiliao.Helper;

import java.lang.reflect.Field;

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

public class HeadZoneBanner implements IHook {
static Class<?> rankFeedList;
static Class<?> feedsHotListFragment2;

static Field head_zone;

@Override
public String getName() {
return "隐藏热榜顶部置顶";
}

@Override
public void init(ClassLoader classLoader) throws Throwable {
rankFeedList = classLoader.loadClass("com.zhihu.android.api.model.RankFeedList");
head_zone = rankFeedList.getDeclaredField("head_zone");
head_zone.setAccessible(true);
feedsHotListFragment2 = classLoader.loadClass("com.zhihu.android.app.feed.ui.fragment.FeedsHotListFragment2");
}

@Override
public void hook() throws Throwable {
XposedBridge.hookAllMethods(feedsHotListFragment2, "postRefreshSucceed", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws IllegalAccessException {
if (Helper.prefs.getBoolean("switch_mainswitch", false)) {
head_zone.set(param.args[0], null);
}
}
});
}
}
53 changes: 53 additions & 0 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/MineHybridView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.shatyuka.zhiliao.hooks;

import android.view.View;

import com.shatyuka.zhiliao.Helper;

import java.lang.reflect.Field;
import java.util.Arrays;

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

public class MineHybridView implements IHook {

static Class<?> mineTabFragment;

static Class<?> mineHybridView;

static Field mineHybridViewField;

@Override
public String getName() {
return "隐藏「我的」底部混合卡片";
}

@Override
public void init(ClassLoader classLoader) throws Throwable {
mineTabFragment = classLoader.loadClass("com.zhihu.android.app.ui.fragment.more.mine.MineTabFragment");
mineHybridView = classLoader.loadClass("com.zhihu.android.app.ui.fragment.more.mine.widget.MineHybridView");

mineHybridViewField = Arrays.stream(mineTabFragment.getDeclaredFields()).filter(field -> field.getType() == mineHybridView).findFirst().get();
mineHybridViewField.setAccessible(true);

}

@Override
public void hook() throws Throwable {

XposedBridge.hookAllMethods(mineTabFragment, "onCreateView", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && Helper.prefs.getBoolean("switch_minehybrid", false)) {
View mineHybridView = (View) mineHybridViewField.get(param.thisObject);
if (mineHybridView != null) {
mineHybridView.setVisibility(View.GONE);
}
}
}
});


}
}
36 changes: 14 additions & 22 deletions app/src/main/java/com/shatyuka/zhiliao/hooks/NavButton.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

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

public class NavButton implements IHook {
static Class<?> BottomNavMenuView;
Expand All @@ -27,39 +27,31 @@ public String getName() {
@Override
public void init(ClassLoader classLoader) throws Throwable {
BottomNavMenuView = classLoader.loadClass("com.zhihu.android.bottomnav.core.BottomNavMenuView");
try {
IMenuItem = classLoader.loadClass("com.zhihu.android.bottomnav.core.a.b");
} catch (ClassNotFoundException e) {
try {
IMenuItem = classLoader.loadClass("com.zhihu.android.bottomnav.core.b.b");
} catch (ClassNotFoundException e2) {
try {
IMenuItem = classLoader.loadClass("com.zhihu.android.bottomnav.core.t.g");
} catch (ClassNotFoundException e3) {
IMenuItem = classLoader.loadClass("com.zhihu.android.bottomnav.core.w.d");
}
}
}

try {
getItemId = IMenuItem.getMethod("getItemId");
} catch (NoSuchMethodException e) {
getItemId = IMenuItem.getMethod("a");
}

Tab_tabView = classLoader.loadClass("com.google.android.material.tabs.TabLayout$Tab").getField("view");
Class<?> tabLayoutTabClass = classLoader.loadClass("com.google.android.material.tabs.TabLayout$Tab");
IMenuItem = Arrays.stream(BottomNavMenuView.getDeclaredMethods())
.filter(method -> method.getReturnType() == tabLayoutTabClass)
.map(method -> method.getParameterTypes()[0]).findFirst().get();


getItemId = Arrays.stream(IMenuItem.getDeclaredMethods())
.filter(method -> method.getReturnType() == String.class).findFirst().get();


Tab_tabView = tabLayoutTabClass.getField("view");
}

@Override
public void hook() throws Throwable {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && (Helper.prefs.getBoolean("switch_vipnav", false) || Helper.prefs.getBoolean("switch_videonav", false)|| Helper.prefs.getBoolean("switch_friendnav", false) || Helper.prefs.getBoolean("switch_panelnav", false))) {
if (Helper.prefs.getBoolean("switch_mainswitch", false) && (Helper.prefs.getBoolean("switch_vipnav", false) || Helper.prefs.getBoolean("switch_videonav", false) || Helper.prefs.getBoolean("switch_friendnav", false) || Helper.prefs.getBoolean("switch_panelnav", false))) {
XposedBridge.hookMethod(Helper.getMethodByParameterTypes(BottomNavMenuView, IMenuItem), new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (("market".equals(getItemId.invoke(param.args[0])) && Helper.prefs.getBoolean("switch_vipnav", false)) ||
("video".equals(getItemId.invoke(param.args[0])) && Helper.prefs.getBoolean("switch_videonav", false)) ||
("friend".equals(getItemId.invoke(param.args[0])) && Helper.prefs.getBoolean("switch_friendnav", false)) ||
("panel".equals(getItemId.invoke(param.args[0]))&& Helper.prefs.getBoolean("switch_panelnav", false))){
("panel".equals(getItemId.invoke(param.args[0])) && Helper.prefs.getBoolean("switch_panelnav", false))) {
((View) Tab_tabView.get(param.getResult())).setVisibility(View.GONE);
}
}
Expand Down
Loading

0 comments on commit aef8941

Please sign in to comment.