Commit 3a7185d0 authored by justin's avatar justin

1.22适配

parent ec7c6e0b
......@@ -27,7 +27,7 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
lintOptions {
disable 'InvalidPackage'
......@@ -35,10 +35,10 @@ android {
}
dependencies {
compileOnly 'com.android.support:appcompat-v7:28.0.0'
compileOnly 'com.android.support:design:28.0.0'
compileOnly 'com.android.support:support-v4:28.0.0'
implementation 'android.arch.lifecycle:common-java8:1.1.1'
compileOnly 'androidx.appcompat:appcompat:1.0.0'
compileOnly 'com.google.android.material:material:1.0.0'
compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.0.0'
compileOnly 'com.alibaba:fastjson:1.2.41'
}
......
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
......@@ -2,7 +2,7 @@ package com.idlefish.flutterboost;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import com.idlefish.flutterboost.interfaces.IContainerRecord;
import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
......
......@@ -6,7 +6,7 @@ import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import com.idlefish.flutterboost.interfaces.*;
......@@ -355,7 +355,7 @@ public class FlutterBoost {
mEngine = new FlutterEngine(mPlatform.getApplication().getApplicationContext(),FlutterLoader.getInstance(),new FlutterJNI(),null,false);
}
// registerPlugins(mEngine);
registerPlugins(mEngine);
// mRegistry = new BoostPluginRegistry(createEngine());
// mPlatform.registerPlugins(mRegistry);
}
......
package com.idlefish.flutterboost;
import android.support.annotation.Nullable;
import android.os.Handler;
import androidx.annotation.Nullable;
import android.util.Log;
import com.idlefish.flutterboost.interfaces.IContainerRecord;
......
package com.idlefish.flutterboost;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import io.flutter.embedding.engine.systemchannels.KeyEventChannel;
import io.flutter.plugin.editing.TextInputPlugin;
public class XAndroidKeyProcessor {
@NonNull
private final KeyEventChannel keyEventChannel;
@NonNull
private final XTextInputPlugin textInputPlugin;
private int combiningCharacter;
public XAndroidKeyProcessor(@NonNull KeyEventChannel keyEventChannel, @NonNull XTextInputPlugin textInputPlugin) {
this.keyEventChannel = keyEventChannel;
this.textInputPlugin = textInputPlugin;
}
public void onKeyUp(@NonNull KeyEvent keyEvent) {
Character complexCharacter = applyCombiningCharacterToBaseCharacter(keyEvent.getUnicodeChar());
keyEventChannel.keyUp(
new KeyEventChannel.FlutterKeyEvent(keyEvent, complexCharacter)
);
}
public void onKeyDown(@NonNull KeyEvent keyEvent) {
if (textInputPlugin.getLastInputConnection() != null
&& textInputPlugin.getInputMethodManager().isAcceptingText()) {
textInputPlugin.getLastInputConnection().sendKeyEvent(keyEvent);
}
Character complexCharacter = applyCombiningCharacterToBaseCharacter(keyEvent.getUnicodeChar());
keyEventChannel.keyDown(
new KeyEventChannel.FlutterKeyEvent(keyEvent, complexCharacter)
);
}
/**
* Applies the given Unicode character in {@code newCharacterCodePoint} to a previously
* entered Unicode combining character and returns the combination of these characters
* if a combination exists.
* <p>
* This method mutates {@link #combiningCharacter} over time to combine characters.
* <p>
* One of the following things happens in this method:
* <ul>
* <li>If no previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint}
* is not a combining character, then {@code newCharacterCodePoint} is returned.</li>
* <li>If no previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint}
* is a combining character, then {@code newCharacterCodePoint} is saved as the
* {@link #combiningCharacter} and null is returned.</li>
* <li>If a previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint}
* is also a combining character, then the {@code newCharacterCodePoint} is combined with
* the existing {@link #combiningCharacter} and null is returned.</li>
* <li>If a previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint}
* is not a combining character, then the {@link #combiningCharacter} is applied to the
* regular {@code newCharacterCodePoint} and the resulting complex character is returned. The
* {@link #combiningCharacter} is cleared.</li>
* </ul>
* <p>
* The following reference explains the concept of a "combining character":
* https://en.wikipedia.org/wiki/Combining_character
*/
@Nullable
private Character applyCombiningCharacterToBaseCharacter(int newCharacterCodePoint) {
if (newCharacterCodePoint == 0) {
return null;
}
Character complexCharacter = (char) newCharacterCodePoint;
boolean isNewCodePointACombiningCharacter = (newCharacterCodePoint & KeyCharacterMap.COMBINING_ACCENT) != 0;
if (isNewCodePointACombiningCharacter) {
// If a combining character was entered before, combine this one with that one.
int plainCodePoint = newCharacterCodePoint & KeyCharacterMap.COMBINING_ACCENT_MASK;
if (combiningCharacter != 0) {
combiningCharacter = KeyCharacterMap.getDeadChar(combiningCharacter, plainCodePoint);
} else {
combiningCharacter = plainCodePoint;
}
} else {
// The new character is a regular character. Apply combiningCharacter to it, if it exists.
if (combiningCharacter != 0) {
int combinedChar = KeyCharacterMap.getDeadChar(combiningCharacter, newCharacterCodePoint);
if (combinedChar > 0) {
complexCharacter = (char) combinedChar;
}
combiningCharacter = 0;
}
}
return complexCharacter;
}
}
\ No newline at end of file
package com.idlefish.flutterboost;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.TextureView;
import io.flutter.Log;
import io.flutter.embedding.engine.renderer.FlutterRenderer;
import io.flutter.embedding.engine.renderer.RenderSurface;
public class XFlutterTextureView extends TextureView implements RenderSurface {
private static final String TAG = "FlutterTextureView";
private boolean isSurfaceAvailableForRendering = false;
private boolean isAttachedToFlutterRenderer = false;
@Nullable
private FlutterRenderer flutterRenderer;
private Surface renderSurface;
// Connects the {@code SurfaceTexture} beneath this {@code TextureView} with Flutter's native code.
// Callbacks are received by this Object and then those messages are forwarded to our
// FlutterRenderer, and then on to the JNI bridge over to native Flutter code.
private final SurfaceTextureListener surfaceTextureListener = new SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
Log.v(TAG, "SurfaceTextureListener.onSurfaceTextureAvailable()");
isSurfaceAvailableForRendering = true;
// If we're already attached to a FlutterRenderer then we're now attached to both a renderer
// and the Android window, so we can begin rendering now.
if (isAttachedToFlutterRenderer) {
connectSurfaceToRenderer();
}
}
@Override
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
Log.v(TAG, "SurfaceTextureListener.onSurfaceTextureSizeChanged()");
if (isAttachedToFlutterRenderer) {
changeSurfaceSize(width, height);
}
}
@Override
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
// Invoked every time a new frame is available. We don't care.
}
@Override
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
Log.v(TAG, "SurfaceTextureListener.onSurfaceTextureDestroyed()");
isSurfaceAvailableForRendering = false;
// If we're attached to a FlutterRenderer then we need to notify it that our SurfaceTexture
// has been destroyed.
if (isAttachedToFlutterRenderer) {
disconnectSurfaceFromRenderer();
}
// Return true to indicate that no further painting will take place
// within this SurfaceTexture.
return true;
}
};
/**
* Constructs a {@code FlutterTextureView} programmatically, without any XML attributes.
*/
public XFlutterTextureView(@NonNull Context context) {
this(context, null);
}
/**
* Constructs a {@code FlutterTextureView} in an XML-inflation-compliant manner.
*/
public XFlutterTextureView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// Listen for when our underlying SurfaceTexture becomes available, changes size, or
// gets destroyed, and take the appropriate actions.
setSurfaceTextureListener(surfaceTextureListener);
}
@Nullable
@Override
public FlutterRenderer getAttachedRenderer() {
return flutterRenderer;
}
/**
* Invoked by the owner of this {@code FlutterTextureView} when it wants to begin rendering
* a Flutter UI to this {@code FlutterTextureView}.
*
* If an Android {@link SurfaceTexture} is available, this method will give that
* {@link SurfaceTexture} to the given {@link FlutterRenderer} to begin rendering
* Flutter's UI to this {@code FlutterTextureView}.
*
* If no Android {@link SurfaceTexture} is available yet, this {@code FlutterTextureView}
* will wait until a {@link SurfaceTexture} becomes available and then give that
* {@link SurfaceTexture} to the given {@link FlutterRenderer} to begin rendering
* Flutter's UI to this {@code FlutterTextureView}.
*/
public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) {
Log.v(TAG, "Attaching to FlutterRenderer.");
if (this.flutterRenderer != null) {
Log.v(TAG, "Already connected to a FlutterRenderer. Detaching from old one and attaching to new one.");
this.flutterRenderer.stopRenderingToSurface();
}
this.flutterRenderer = flutterRenderer;
isAttachedToFlutterRenderer = true;
// If we're already attached to an Android window then we're now attached to both a renderer
// and the Android window. We can begin rendering now.
if (isSurfaceAvailableForRendering) {
Log.v(TAG, "Surface is available for rendering. Connecting FlutterRenderer to Android surface.");
connectSurfaceToRenderer();
}
}
/**
* Invoked by the owner of this {@code FlutterTextureView} when it no longer wants to render
* a Flutter UI to this {@code FlutterTextureView}.
*
* This method will cease any on-going rendering from Flutter to this {@code FlutterTextureView}.
*/
public void detachFromRenderer() {
if (flutterRenderer != null) {
// If we're attached to an Android window then we were rendering a Flutter UI. Now that
// this FlutterTextureView is detached from the FlutterRenderer, we need to stop rendering.
// TODO(mattcarroll): introduce a isRendererConnectedToSurface() to wrap "getWindowToken() != null"
if (getWindowToken() != null) {
Log.v(TAG, "Disconnecting FlutterRenderer from Android surface.");
disconnectSurfaceFromRenderer();
}
flutterRenderer = null;
isAttachedToFlutterRenderer = false;
} else {
Log.w(TAG, "detachFromRenderer() invoked when no FlutterRenderer was attached.");
}
}
// FlutterRenderer and getSurfaceTexture() must both be non-null.
private void connectSurfaceToRenderer() {
if (flutterRenderer == null || getSurfaceTexture() == null) {
throw new IllegalStateException("connectSurfaceToRenderer() should only be called when flutterRenderer and getSurfaceTexture() are non-null.");
}
// flutterRenderer.startRenderingToSurface(new Surface(getSurfaceTexture()));
renderSurface = new Surface(getSurfaceTexture());
flutterRenderer.startRenderingToSurface(renderSurface);
}
// FlutterRenderer must be non-null.
private void changeSurfaceSize(int width, int height) {
if (flutterRenderer == null) {
throw new IllegalStateException("changeSurfaceSize() should only be called when flutterRenderer is non-null.");
}
Log.v(TAG, "Notifying FlutterRenderer that Android surface size has changed to " + width + " x " + height);
flutterRenderer.surfaceChanged(width, height);
}
// FlutterRenderer must be non-null.
private void disconnectSurfaceFromRenderer() {
if (flutterRenderer == null) {
throw new IllegalStateException("disconnectSurfaceFromRenderer() should only be called when flutterRenderer is non-null.");
}
flutterRenderer.stopRenderingToSurface();
if(renderSurface!=null){
renderSurface.release();
renderSurface = null;
}
}
}
\ No newline at end of file
......@@ -2,9 +2,9 @@ package com.idlefish.flutterboost.containers;
import android.app.Activity;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.LifecycleRegistry;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
......@@ -15,13 +15,11 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.*;
import android.widget.*;
import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import com.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import io.flutter.Log;
......@@ -58,8 +56,6 @@ public class BoostFlutterActivity extends Activity
// Default configuration.
protected static final String DEFAULT_BACKGROUND_MODE = BackgroundMode.opaque.name();
private static XPlatformPlugin sXPlatformPlugin;
public static Intent createDefaultIntent(@NonNull Context launchContext) {
return withNewEngine().build(launchContext);
}
......@@ -247,7 +243,7 @@ public class BoostFlutterActivity extends Activity
}
protected XFlutterView getFlutterView() {
protected FlutterView getFlutterView() {
return delegate.getFlutterView();
}
......@@ -445,9 +441,13 @@ public class BoostFlutterActivity extends Activity
}
@Nullable
@Override
public XPlatformPlugin providePlatformPlugin(@NonNull FlutterEngine flutterEngine) {
return BoostViewUtils.getPlatformPlugin(flutterEngine.getPlatformChannel());
public PlatformPlugin providePlatformPlugin(
@Nullable Activity activity, @NonNull FlutterEngine flutterEngine) {
if (activity != null) {
return new PlatformPlugin(getActivity(), flutterEngine.getPlatformChannel());
} else {
return null;
}
}
/**
......
package com.idlefish.flutterboost.containers;
import com.idlefish.flutterboost.XPlatformPlugin;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
class BoostViewUtils {
private static volatile XPlatformPlugin mInstance;
private BoostViewUtils() {
}
public static XPlatformPlugin getPlatformPlugin(PlatformChannel channel) {
if (mInstance == null) {
synchronized (BoostViewUtils.class) {
if (mInstance == null) {
mInstance = new XPlatformPlugin(channel);
}
}
}
return mInstance;
}
}
......@@ -2,15 +2,14 @@ package com.idlefish.flutterboost.containers;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.arch.lifecycle.Lifecycle;
import androidx.lifecycle.Lifecycle;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.*;
import java.io.Serializable;
......@@ -21,9 +20,6 @@ import java.util.Map;
import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.Utils;
import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import com.idlefish.flutterboost.interfaces.IContainerRecord;
import com.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import com.idlefish.flutterboost.interfaces.IOperateSyncer;
import io.flutter.Log;
......@@ -48,9 +44,9 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
@Nullable
private FlutterSplashView flutterSplashView;
@Nullable
private XFlutterView flutterView;
private FlutterView flutterView;
@Nullable
private XPlatformPlugin platformPlugin;
private PlatformPlugin platformPlugin;
private boolean isFlutterEngineFromHost;
......@@ -75,7 +71,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
return flutterEngine;
}
public XFlutterView getFlutterView() {
public FlutterView getFlutterView() {
return flutterView;
}
......@@ -96,7 +92,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
// TODO(mattcarroll): the PlatformPlugin needs to be reimagined because it implicitly takes
// control of the entire window. This is unacceptable for non-fullscreen
// use-cases.
platformPlugin = host.providePlatformPlugin(flutterEngine);
platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine);
host.configureFlutterEngine(flutterEngine);
......@@ -133,7 +129,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
mSyncer = FlutterBoost.instance().containerManager().generateSyncer(this);
ensureAlive();
flutterView = new XFlutterView(host.getActivity(), FlutterBoost.instance().platform().renderMode(), host.getTransparencyMode());
flutterView = new FlutterView(host.getActivity(), FlutterBoost.instance().platform().renderMode(), host.getTransparencyMode());
flutterSplashView = new FlutterSplashView(host.getContext());
......@@ -183,17 +179,22 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
}
if(platformPlugin!=null)
platformPlugin.attachToActivity( host.getActivity());
}
public void onPostResume() {
void onPostResume() {
Log.v(TAG, "onPostResume()");
ensureAlive();
if (flutterEngine != null) {
if (platformPlugin != null) {
platformPlugin.updateSystemUiOverlays();
}
} else {
Log.w(TAG, "onPostResume() invoked before FlutterFragment was attached to an Activity.");
}
}
......@@ -219,22 +220,17 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
ensureAlive();
flutterView.release();
// flutterView.release();
}
public void onDetach() {
Log.v(TAG, "onDetach()");
ensureAlive();
// Null out the platformPlugin to avoid a possible retain cycle between the plugin, this Fragment,
// and this Fragment's Activity.
if (platformPlugin != null) {
platformPlugin.detachActivity(getContextActivity());
platformPlugin.destroy();
platformPlugin = null;
}
if(ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE!=0 &&
ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE==this.host.getActivity().hashCode()){
flutterEngine.getActivityControlSurface().detachFromActivityForConfigChanges();
......@@ -244,11 +240,22 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
}
// public void onBackPressed() {
// ensureAlive();
// if (flutterEngine != null) {
// Log.v(TAG, "Forwarding onBackPressed() to FlutterEngine.");
// flutterEngine.getNavigationChannel().popRoute();
// } else {
// Log.w(TAG, "Invoked onBackPressed() before FlutterFragment was attached to an Activity.");
// }
// }
public void onBackPressed() {
mSyncer.onBackPressed();
ensureAlive();
}
......@@ -466,9 +473,8 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
* Hook for the host to create/provide a {@link PlatformPlugin} if the associated
* Flutter experience should control system chrome.
*/
@Nullable
XPlatformPlugin providePlatformPlugin( @NonNull FlutterEngine flutterEngine);
PlatformPlugin providePlatformPlugin(
@Nullable Activity activity, @NonNull FlutterEngine flutterEngine);
/**
* Hook for the host to configure the {@link FlutterEngine} as desired.
*/
......
package com.idlefish.flutterboost.containers;
import android.app.Activity;
import android.arch.lifecycle.Lifecycle;
import androidx.lifecycle.Lifecycle;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import io.flutter.embedding.android.*;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.plugin.platform.PlatformPlugin;
import java.util.HashMap;
import java.util.Map;
......@@ -233,7 +232,7 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm
private FlutterActivityAndFragmentDelegate delegate;
protected XFlutterView getFlutterView() {
protected FlutterView getFlutterView() {
return delegate.getFlutterView();
}
......@@ -467,8 +466,13 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm
@Nullable
@Override
public XPlatformPlugin providePlatformPlugin( @NonNull FlutterEngine flutterEngine) {
return BoostViewUtils.getPlatformPlugin(flutterEngine.getPlatformChannel());
public PlatformPlugin providePlatformPlugin(
@Nullable Activity activity, @NonNull FlutterEngine flutterEngine) {
if (activity != null) {
return new PlatformPlugin(getActivity(), flutterEngine.getPlatformChannel());
} else {
return null;
}
}
/**
......
......@@ -4,8 +4,8 @@ import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
......@@ -29,7 +29,7 @@ public class FlutterSplashView extends FrameLayout {
@Nullable
private SplashScreen splashScreen;
@Nullable
private XFlutterView flutterView;
private FlutterView flutterView;
@Nullable
private View splashScreenView;
@Nullable
......@@ -103,7 +103,7 @@ public class FlutterSplashView extends FrameLayout {
* If no {@code splashScreen} is provided, this {@code FlutterSplashView} displays the
* given {@code flutterView} on its own.
*/
public void displayFlutterViewWithSplash(@NonNull XFlutterView flutterView, @Nullable SplashScreen splashScreen) {
public void displayFlutterViewWithSplash(@NonNull FlutterView flutterView, @Nullable SplashScreen splashScreen) {
// If we were displaying a previous FlutterView, remove it.
if (this.flutterView != null) {
this.flutterView.removeOnFirstFrameRenderedListener(onFirstFrameRenderedListener);
......
......@@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
compileSdkVersion 29
lintOptions {
disable 'InvalidPackage'
......@@ -38,7 +38,7 @@ android {
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
buildTypes {
......@@ -56,11 +56,11 @@ flutter {
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.alibaba:fastjson:1.2.41'
}
......@@ -3,10 +3,10 @@ package com.taobao.idlefish.flutterboostexample;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.view.ViewCompat;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
......
......@@ -6,9 +6,9 @@ import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
......
package com.taobao.idlefish.flutterboostexample;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
......
package com.taobao.idlefish.flutterboostexample;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
......
......@@ -5,7 +5,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'com.android.tools.build:gradle:3.2.0'
}
}
......
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
......@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
......@@ -18,7 +18,8 @@ class _MyAppState extends State<MyApp> {
super.initState();
FlutterBoost.singleton.registerPageBuilders({
'embeded': (pageName, params, _)=>EmbededFirstRouteWidget(),
'/': (pageName, params, _) => Container(),
'embeded': (pageName, params, _) => EmbededFirstRouteWidget(),
'first': (pageName, params, _) => FirstRouteWidget(),
'firstFirst': (pageName, params, _) => FirstFirstRouteWidget(),
'second': (pageName, params, _) => SecondRouteWidget(),
......@@ -26,25 +27,28 @@ class _MyAppState extends State<MyApp> {
'tab': (pageName, params, _) => TabRouteWidget(),
'platformView': (pageName, params, _) => PlatformRouteWidget(),
'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params),
///可以在native层通过 getContainerParams 来传递参数
'flutterPage': (pageName, params, _) {
print("flutterPage params:$params");
return FlutterRouteWidget(params:params);
return FlutterRouteWidget(params: params);
},
'f2f_first': (pageName, params, _) => F2FFirstPage(),
'f2f_second': (pageName, params, _) => F2FSecondPage(),
});
FlutterBoost.singleton.addBoostNavigatorObserver(TestBoostNavigatorObserver());
FlutterBoost.singleton.addContainerObserver((
ContainerOperation operation, BoostContainerSettings settings){
FlutterBoost.singleton
.addBoostNavigatorObserver(TestBoostNavigatorObserver());
FlutterBoost.singleton.addContainerObserver(
(ContainerOperation operation, BoostContainerSettings settings) {
operation;
settings;
});
FlutterBoostAPI.singleton.routeSettingsBuilder = (String url,
{Map<String, dynamic> urlParams, Map<String, dynamic> exts}) => BoostRouteSettings(
{Map<String, dynamic> urlParams, Map<String, dynamic> exts}) =>
BoostRouteSettings(
uniqueId: '${url}_${DateTime.now().millisecondsSinceEpoch}',
name: url,
params: urlParams,
......@@ -53,22 +57,47 @@ class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
return WidgetsApp(
title: 'Flutter Boost example',
builder: FlutterBoost.init(postPush: _onRoutePushed),
home: Container(
color:Colors.white
));
color: Colors.white,
localizationsDelegates: [DefaultMaterialLocalizations.delegate],
onUnknownRoute:(RouteSettings settings){
if(settings.name=="/")
return unKnownRoute( settings);
},
// home: Container(),
);
}
void _onRoutePushed(
String pageName, String uniqueId, Map params, Route route, Future _) {
Route unKnownRoute(RouteSettings settings){
return new PageRouteBuilder<dynamic>(
pageBuilder: (BuildContext context,Animation<double> animation,
Animation<double> secondaryAnimation){
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("First Page",textDirection: TextDirection.ltr,),
const Padding(padding: const EdgeInsets.all(10.0)),
new GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: new Container(
padding: const EdgeInsets.all(10.0),
color:Colors.blue,
child: const Text("Back"),
),
)
]
);
}
);
}
void _onRoutePushed(
String pageName, String uniqueId, Map params, Route route, Future _) {}
}
class TestBoostNavigatorObserver extends ContainerNavigatorObserver{
class TestBoostNavigatorObserver extends ContainerNavigatorObserver {
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
route.settings.name!="/";
route.settings.name != "/";
//1. 底下
//新页面已经push完成
......@@ -86,10 +115,8 @@ class TestBoostNavigatorObserver extends ContainerNavigatorObserver{
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
print("flutterboost#didReplace");
}
void willPush(Route<dynamic> route, Route<dynamic> previousRoute) {
void willPush(Route<dynamic> route, Route<dynamic> previousRoute) {
print("flutterboost#willPush");
}
}
......@@ -183,6 +183,9 @@ class BoostContainerState extends NavigatorState {
@override
Future<bool> maybePop<T extends Object>([T result]) async {
if(routerHistory.isEmpty)
pop(result);
final Route<T> route = routerHistory.last;
final RoutePopDisposition disposition = await route.willPop();
if (mounted) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment