feature: scheme handler now support refresh in current UI if matched.

This commit is contained in:
cgspine
2020-06-06 15:16:09 +08:00
parent 3aa1c0aacb
commit 609af678ef
14 changed files with 149 additions and 43 deletions
@@ -25,6 +25,7 @@ import java.lang.annotation.Target;
public @interface ActivityScheme {
String name();
String[] required() default {};
boolean useRefreshIfCurrentMatched() default false;
Class<?> customMatcher() default void.class;
Class<?> customFactory() default void.class;
String[] keysWithIntValue() default {};
@@ -26,6 +26,7 @@ public @interface FragmentScheme {
String name();
Class<?>[] activities();
String[] required() default {};
boolean useRefreshIfCurrentMatched() default false;
Class<?> customMatcher() default void.class;
boolean forceNewActivity() default false;
String forceNewActivityKey() default "";
@@ -172,6 +172,8 @@ public class SchemeProcessor extends BaseProcessor {
/**/.add("new $T(", ActivitySchemeItem)
/*---*/.add("$T.class", elementName)
/*---*/.add(",")
/*---*/.add("$L", annotation.useRefreshIfCurrentMatched())
/*---*/.add(",")
/*---*/.add(customFactory)
/*---*/.add(",")
/*---*/.add("required")
@@ -212,6 +214,8 @@ public class SchemeProcessor extends BaseProcessor {
/**/.add("new $T(", FragmentSchemeItem)
/*---*/.add("$T.class", elementName)
/*---*/.add(",")
/*---*/.add("$L", annotation.useRefreshIfCurrentMatched())
/*---*/.add(",")
/*---*/.add(activities)
/*---*/.add(",")
/*---*/.add(customFactory)
@@ -25,6 +25,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.qmuiteam.qmui.arch.scheme.ActivitySchemeRefreshable;
import com.qmuiteam.qmui.util.QMUIDisplayHelper;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
@@ -41,7 +42,7 @@ import static com.qmuiteam.qmui.arch.SwipeBackLayout.EDGE_LEFT;
import static com.qmuiteam.qmui.arch.SwipeBackLayout.EDGE_RIGHT;
import static com.qmuiteam.qmui.arch.SwipeBackLayout.EDGE_TOP;
public class QMUIActivity extends InnerBaseActivity {
public class QMUIActivity extends InnerBaseActivity implements ActivitySchemeRefreshable {
private static final String TAG = "QMUIActivity";
private SwipeBackLayout.ListenerRemover mListenerRemover;
private SwipeBackgroundView mSwipeBackgroundView;
@@ -328,4 +329,9 @@ public class QMUIActivity extends InnerBaseActivity {
}
super.finish();
}
@Override
public void refreshFromScheme(@Nullable Intent intent) {
}
}
@@ -61,6 +61,7 @@ import com.qmuiteam.qmui.arch.effect.QMUIFragmentEffectRegistry;
import com.qmuiteam.qmui.arch.effect.QMUIFragmentResultEffectHandler;
import com.qmuiteam.qmui.arch.record.LatestVisitArgumentCollector;
import com.qmuiteam.qmui.arch.record.RecordArgumentEditor;
import com.qmuiteam.qmui.arch.scheme.FragmentSchemeRefreshable;
import com.qmuiteam.qmui.arch.scheme.QMUISchemeHandler;
import com.qmuiteam.qmui.util.QMUIDisplayHelper;
import com.qmuiteam.qmui.util.QMUIKeyboardHelper;
@@ -89,7 +90,7 @@ import static com.qmuiteam.qmui.arch.SwipeBackLayout.EDGE_TOP;
* Created by cgspine on 15/9/14.
*/
public abstract class QMUIFragment extends Fragment implements
QMUIFragmentLazyLifecycleOwner.Callback, LatestVisitArgumentCollector {
QMUIFragmentLazyLifecycleOwner.Callback, LatestVisitArgumentCollector, FragmentSchemeRefreshable {
static final String SWIPE_BACK_VIEW = "swipe_back_view";
private static final String TAG = QMUIFragment.class.getSimpleName();
@@ -1324,6 +1325,11 @@ public abstract class QMUIFragment extends Fragment implements
return true;
}
@Override
public void refreshFromScheme(@Nullable Bundle bundle) {
}
private void notifyFragmentVisibleToUserChanged(boolean isVisibleToUser) {
if (mLazyViewLifecycleOwner != null) {
mLazyViewLifecycleOwner.setViewVisible(isVisibleToUser);
@@ -37,6 +37,7 @@ class ActivitySchemeItem extends SchemeItem {
private final Class<? extends QMUISchemeIntentFactory> mIntentFactoryCls;
public ActivitySchemeItem(@NonNull Class<? extends Activity> activityClass,
boolean useRefreshIfMatchedCurrent,
@Nullable Class<? extends QMUISchemeIntentFactory> intentFactoryCls,
@Nullable ArrayMap<String, String> required,
@Nullable String[] keysForInt,
@@ -45,7 +46,7 @@ class ActivitySchemeItem extends SchemeItem {
@Nullable String[] keysForFloat,
@Nullable String[] keysForDouble,
@Nullable Class<? extends QMUISchemeMatcher> schemeMatcherCls) {
super(required, keysForInt, keysForBool, keysForLong, keysForFloat, keysForDouble, schemeMatcherCls);
super(required, useRefreshIfMatchedCurrent, keysForInt, keysForBool, keysForLong, keysForFloat, keysForDouble, schemeMatcherCls);
mActivityClass = activityClass;
mIntentFactoryCls = intentFactoryCls;
}
@@ -79,7 +80,12 @@ class ActivitySchemeItem extends SchemeItem {
}
Intent intent = factory.factory(activity, mActivityClass, scheme);
activity.startActivity(intent);
if(isUseRefreshIfMatchedCurrent() && mActivityClass == activity.getClass() && activity instanceof ActivitySchemeRefreshable){
((ActivitySchemeRefreshable) activity).refreshFromScheme(intent);
}else{
activity.startActivity(intent);
}
return true;
}
return false;
@@ -0,0 +1,25 @@
/*
* Tencent is pleased to support the open source community by making QMUI_Android available.
*
* Copyright (C) 2017-2018 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the MIT License (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.qmuiteam.qmui.arch.scheme;
import android.content.Intent;
import androidx.annotation.Nullable;
public interface ActivitySchemeRefreshable {
void refreshFromScheme(@Nullable Intent intent);
}
@@ -18,10 +18,12 @@ package com.qmuiteam.qmui.arch.scheme;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.ArrayMap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.qmuiteam.qmui.QMUILog;
import com.qmuiteam.qmui.arch.QMUIFragment;
@@ -41,6 +43,7 @@ class FragmentSchemeItem extends SchemeItem {
private final Class<? extends QMUISchemeFragmentFactory> mFragmentFactoryCls;
public FragmentSchemeItem(@NonNull Class<? extends QMUIFragment> fragmentCls,
boolean useRefreshIfMatchedCurrent,
@NonNull Class<? extends QMUIFragmentActivity>[] activityClsList,
@Nullable Class<? extends QMUISchemeFragmentFactory> fragmentFactoryCls,
boolean forceNewActivity,
@@ -52,7 +55,7 @@ class FragmentSchemeItem extends SchemeItem {
@Nullable String[] keysForFloat,
@Nullable String[] keysForDouble,
@Nullable Class<? extends QMUISchemeMatcher> schemeMatcherCls) {
super(required, keysForInt, keysForBool, keysForLong, keysForFloat, keysForDouble, schemeMatcherCls);
super(required, useRefreshIfMatchedCurrent, keysForInt, keysForBool, keysForLong, keysForFloat, keysForDouble, schemeMatcherCls);
mFragmentCls = fragmentCls;
mActivityClsList = activityClsList;
mForceNewActivity = forceNewActivity;
@@ -105,14 +108,28 @@ class FragmentSchemeItem extends SchemeItem {
}
QMUIFragmentActivity fragmentActivity = (QMUIFragmentActivity) activity;
QMUIFragment fragment = factory.factory(mFragmentCls, scheme);
if (fragment != null) {
Bundle args = factory.factory(scheme);
Fragment currentFragment = fragmentActivity.getCurrentFragment();
if(isUseRefreshIfMatchedCurrent()
&& currentFragment != null
&& currentFragment.getClass() == mFragmentCls
&& currentFragment instanceof FragmentSchemeRefreshable){
((FragmentSchemeRefreshable) currentFragment).refreshFromScheme(args);
return true;
}
try {
QMUIFragment fragment = mFragmentCls.newInstance();
fragment.setArguments(args);
int commitId = fragmentActivity.startFragment(fragment);
if (commitId == -1) {
QMUILog.d(QMUISchemeHandler.TAG, "start fragment failed.");
return false;
}
return true;
} catch (Exception e) {
QMUILog.printErrStackTrace(QMUISchemeHandler.TAG, e,
"Error to create fragment: %s", mFragmentCls.getSimpleName());
}
return false;
}
@@ -0,0 +1,25 @@
/*
* Tencent is pleased to support the open source community by making QMUI_Android available.
*
* Copyright (C) 2017-2018 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the MIT License (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.qmuiteam.qmui.arch.scheme;
import android.os.Bundle;
import androidx.annotation.Nullable;
public interface FragmentSchemeRefreshable {
void refreshFromScheme(@Nullable Bundle bundle);
}
@@ -35,36 +35,7 @@ public class QMUIDefaultSchemeFragmentFactory implements QMUISchemeFragmentFacto
@Override
@Nullable
public QMUIFragment factory(@NonNull Class<? extends QMUIFragment> fragmentCls,
@Nullable Map<String, SchemeValue> scheme) {
try {
QMUIFragment fragment = fragmentCls.newInstance();
fragment.setArguments(createBundleForScheme(scheme));
return fragment;
} catch (Exception e) {
QMUILog.printErrStackTrace(QMUISchemeHandler.TAG, e,
"Error to create fragment: %s", fragmentCls.getSimpleName());
return null;
}
}
@Override
@Nullable
public Intent factory(@NonNull Activity activity,
@NonNull Class<? extends QMUIFragmentActivity>[] activityClassList,
@NonNull Class<? extends QMUIFragment> fragmentCls,
@Nullable Map<String, SchemeValue> scheme) {
Bundle bundle = createBundleForScheme(scheme);
if (activityClassList.length == 0) {
return null;
}
Intent intent = QMUIFragmentActivity.intentOf(activity, activityClassList[0], fragmentCls, bundle);
intent.putExtra(ARG_FROM_SCHEME, true);
return intent;
}
@NonNull
private Bundle createBundleForScheme(@Nullable Map<String, SchemeValue> scheme) {
public Bundle factory(@Nullable Map<String, SchemeValue> scheme) {
Bundle bundle = new Bundle();
bundle.putBoolean(QMUISchemeHandler.ARG_FROM_SCHEME, true);
if (scheme != null && !scheme.isEmpty()) {
@@ -89,6 +60,21 @@ public class QMUIDefaultSchemeFragmentFactory implements QMUISchemeFragmentFacto
return bundle;
}
@Override
@Nullable
public Intent factory(@NonNull Activity activity,
@NonNull Class<? extends QMUIFragmentActivity>[] activityClassList,
@NonNull Class<? extends QMUIFragment> fragmentCls,
@Nullable Map<String, SchemeValue> scheme) {
Bundle bundle = factory(scheme);
if (activityClassList.length == 0) {
return null;
}
Intent intent = QMUIFragmentActivity.intentOf(activity, activityClassList[0], fragmentCls, bundle);
intent.putExtra(ARG_FROM_SCHEME, true);
return intent;
}
@Override
public boolean shouldBlockJump(@NonNull Activity activity,
@NonNull Class<? extends QMUIFragment> fragmentCls,
@@ -18,6 +18,7 @@ package com.qmuiteam.qmui.arch.scheme;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -29,8 +30,7 @@ import java.util.Map;
public interface QMUISchemeFragmentFactory {
@Nullable
QMUIFragment factory(@NonNull Class<? extends QMUIFragment> fragmentCls,
@Nullable Map<String, SchemeValue> scheme);
Bundle factory(@Nullable Map<String, SchemeValue> scheme);
@Nullable
Intent factory(@NonNull Activity activity,
@@ -44,7 +44,10 @@ public abstract class SchemeItem {
@Nullable
private Class<? extends QMUISchemeMatcher> mSchemeMatcherCls;
private boolean mUseRefreshIfMatchedCurrent;
public SchemeItem(@Nullable ArrayMap<String, String> required,
boolean useRefreshIfMatchedCurrent,
@Nullable String[] keysForInt,
@Nullable String[] keysForBool,
@Nullable String[] keysForLong,
@@ -52,6 +55,7 @@ public abstract class SchemeItem {
@Nullable String[] keysForDouble,
@Nullable Class<? extends QMUISchemeMatcher> schemeMatcherCls) {
mRequired = required;
mUseRefreshIfMatchedCurrent = useRefreshIfMatchedCurrent;
mKeysForInt = keysForInt;
mKeysForBool = keysForBool;
mKeysForLong = keysForLong;
@@ -60,6 +64,10 @@ public abstract class SchemeItem {
mSchemeMatcherCls = schemeMatcherCls;
}
public boolean isUseRefreshIfMatchedCurrent() {
return mUseRefreshIfMatchedCurrent;
}
@Nullable
public Map<String, SchemeValue> convertFrom(@Nullable Map<String, String> schemeParams) {
if (schemeParams == null || schemeParams.isEmpty()) {
@@ -17,11 +17,12 @@
package com.qmuiteam.qmuidemo.activity;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.qmuiteam.qmui.arch.annotation.ActivityScheme;
import com.qmuiteam.qmui.widget.QMUITopBarLayout;
import com.qmuiteam.qmuidemo.R;
@@ -31,9 +32,13 @@ import com.qmuiteam.qmuidemo.fragment.lab.QDArchTestFragment;
import butterknife.BindView;
import butterknife.ButterKnife;
@ActivityScheme(name = "arch", required = {"aa", "bb=3"}, keysWithBoolValue = {"aa"})
@ActivityScheme(name = "arch",
useRefreshIfCurrentMatched = true,
required = {"aa", "bb=3"},
keysWithBoolValue = {"aa"})
public class ArchTestActivity extends BaseActivity {
@BindView(R.id.topbar) QMUITopBarLayout mTopBar;
@BindView(R.id.topbar)
QMUITopBarLayout mTopBar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -56,4 +61,5 @@ public class ArchTestActivity extends BaseActivity {
mTopBar.setTitle("Arch Test");
QDArchTestFragment.injectEntrance(mTopBar);
}
}
@@ -48,6 +48,7 @@ import com.qmuiteam.qmuidemo.fragment.components.viewpager.QDLazyTestObserver;
import com.qmuiteam.qmuidemo.lib.Group;
import com.qmuiteam.qmuidemo.lib.annotation.Widget;
import com.qmuiteam.qmuidemo.manager.QDDataManager;
import com.qmuiteam.qmuidemo.manager.QDSchemeManager;
import com.qmuiteam.qmuidemo.model.QDItemDescription;
import java.util.HashMap;
@@ -59,6 +60,7 @@ import butterknife.ButterKnife;
@Widget(group = Group.Other, name = "内容自适应,超过父容器则滚动")
@FragmentScheme(
name = "tab",
useRefreshIfCurrentMatched = true,
activities = {QDMainActivity.class},
required = {"mode=2", "name"},
keysWithIntValue = {"mode"})
@@ -235,6 +237,12 @@ public class QDTabSegmentScrollableModeFragment extends BaseFragment {
builder.textColor(R.attr.app_skin_common_desc_text_color);
}
});
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
QDSchemeManager.getInstance().handle("qmui://tab?mode=2&name=xixi");
}
});
view = textView;
mPageMap.put(page, view);
}
@@ -289,4 +297,11 @@ public class QDTabSegmentScrollableModeFragment extends BaseFragment {
return position;
}
}
@Override
public void refreshFromScheme(@Nullable Bundle bundle) {
Toast.makeText(getContext(),
"refreshFromScheme: name = " + bundle.getString("name"),
Toast.LENGTH_SHORT).show();
}
}