This repository has been archived by the owner on Mar 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 101
TiFragmentPlugin #49
Merged
Merged
TiFragmentPlugin #49
Changes from 6 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
a5f5be2
Add FragmentPlugin for Ti
f9ec4e6
Merge commit '687a9ec508b5367f44f63c50149d420fff439bc8' into feature/…
e033cda
Add before/after postfixes
3d1b2e0
Add plugin headers
8297ca2
Merge branch 'feature/add-fragment-delegate' into feature/composite_f…
2b327aa
Rename overridden methods
a3b81f4
Fix missing delegate call
passsy 20e3b22
Add fragment to plugin test
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
258 changes: 258 additions & 0 deletions
258
plugin/src/main/java/net/grandcentrix/thirtyinch/plugin/TiFragmentPlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
/* | ||
* Copyright (C) 2016 grandcentrix GmbH | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* 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 net.grandcentrix.thirtyinch.plugin; | ||
|
||
|
||
import com.pascalwelsch.compositeandroid.fragment.FragmentPlugin; | ||
|
||
import net.grandcentrix.thirtyinch.BindViewInterceptor; | ||
import net.grandcentrix.thirtyinch.Removable; | ||
import net.grandcentrix.thirtyinch.TiFragment; | ||
import net.grandcentrix.thirtyinch.TiPresenter; | ||
import net.grandcentrix.thirtyinch.TiView; | ||
import net.grandcentrix.thirtyinch.internal.DelegatedTiFragment; | ||
import net.grandcentrix.thirtyinch.internal.InterceptableViewBinder; | ||
import net.grandcentrix.thirtyinch.internal.TiFragmentDelegate; | ||
import net.grandcentrix.thirtyinch.internal.TiLoggingTagProvider; | ||
import net.grandcentrix.thirtyinch.internal.TiPresenterProvider; | ||
import net.grandcentrix.thirtyinch.internal.TiViewProvider; | ||
import net.grandcentrix.thirtyinch.util.AndroidDeveloperOptions; | ||
import net.grandcentrix.thirtyinch.util.AnnotationUtil; | ||
|
||
import android.os.Bundle; | ||
import android.support.annotation.NonNull; | ||
import android.support.annotation.Nullable; | ||
import android.support.v4.app.Fragment; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* Adds a {@link TiPresenter} to a Fragment. Can be used for both, {@link Fragment} and | ||
* {@link android.support.v4.app.DialogFragment} | ||
* | ||
* @param <P> {@link TiPresenter} with will be attached | ||
* @param <V> View, expected by the {@link TiPresenter} | ||
*/ | ||
public class TiFragmentPlugin<P extends TiPresenter<V>, V extends TiView> extends FragmentPlugin | ||
implements TiViewProvider<V>, DelegatedTiFragment, TiLoggingTagProvider, | ||
InterceptableViewBinder<V> { | ||
|
||
private String TAG = this.getClass().getSimpleName() | ||
+ "@" + Integer.toHexString(this.hashCode()); | ||
|
||
private TiFragmentDelegate<P, V> mDelegate; | ||
|
||
/** | ||
* Binds a {@link TiPresenter} returned by the {@link TiPresenterProvider} to the {@link | ||
* Fragment} and all future {@link Fragment} instances created due to configuration changes. | ||
* The provider will be only called once during {@link TiFragmentPlugin#onCreate(Bundle)}. This | ||
* lets you inject objects which require a {@link android.content.Context} and can't be | ||
* instantiated earlier. Using the interface also prevents instantiating the (possibly) heavy | ||
* {@link TiPresenter} which will never be used when a presenter is already created for this | ||
* {@link Fragment}. | ||
* | ||
* @param presenterProvider callback returning the presenter. | ||
*/ | ||
public TiFragmentPlugin(@NonNull final TiPresenterProvider<P> presenterProvider) { | ||
mDelegate = new TiFragmentDelegate<>(this, this, presenterProvider, this); | ||
} | ||
|
||
@NonNull | ||
@Override | ||
public Removable addBindViewInterceptor(@NonNull final BindViewInterceptor interceptor) { | ||
return mDelegate.addBindViewInterceptor(interceptor); | ||
} | ||
|
||
/** | ||
* @return the cached result of {@link BindViewInterceptor#intercept(TiView)} | ||
*/ | ||
@Nullable | ||
@Override | ||
public V getInterceptedViewOf(@NonNull final BindViewInterceptor interceptor) { | ||
return mDelegate.getInterceptedViewOf(interceptor); | ||
} | ||
|
||
/** | ||
* @param predicate filter the results | ||
* @return all interceptors matching the filter | ||
*/ | ||
@NonNull | ||
@Override | ||
public List<BindViewInterceptor> getInterceptors( | ||
@NonNull final Filter<BindViewInterceptor> predicate) { | ||
return mDelegate.getInterceptors(predicate); | ||
} | ||
|
||
|
||
@Override | ||
public String getLoggingTag() { | ||
return TAG; | ||
} | ||
|
||
public P getPresenter() { | ||
return mDelegate.getPresenter(); | ||
} | ||
|
||
/** | ||
* Invalidates the cache of the latest bound view. Forces the next binding of the view to run | ||
* through all the interceptors (again). | ||
*/ | ||
@Override | ||
public void invalidateView() { | ||
mDelegate.invalidateView(); | ||
} | ||
|
||
@Override | ||
public boolean isDontKeepActivitiesEnabled() { | ||
return AndroidDeveloperOptions.isDontKeepActivitiesEnabled(getFragment().getActivity()); | ||
} | ||
|
||
@Override | ||
public boolean isFragmentAdded() { | ||
return getFragment().isAdded(); | ||
} | ||
|
||
@Override | ||
public boolean isFragmentDetached() { | ||
return getFragment().isDetached(); | ||
} | ||
|
||
@Override | ||
public boolean isHostingActivityChangingConfigurations() { | ||
return getFragment().getActivity().isChangingConfigurations(); | ||
} | ||
|
||
@Override | ||
public boolean isHostingActivityFinishing() { | ||
return getFragment().getActivity().isFinishing(); | ||
} | ||
|
||
@Override | ||
public void onCreate(final Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
mDelegate.onCreate_afterSuper(savedInstanceState); | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, | ||
@Nullable final Bundle savedInstanceState) { | ||
mDelegate.onCreateView_beforeSuper(inflater, container, savedInstanceState); | ||
return super.onCreateView(inflater, container, savedInstanceState); | ||
} | ||
|
||
@Override | ||
public void onDestroy() { | ||
super.onDestroy(); | ||
mDelegate.onDestroy_afterSuper(); | ||
} | ||
|
||
@Override | ||
public void onDestroyView() { | ||
mDelegate.onDestroyView_beforeSuper(); | ||
super.onDestroyView(); | ||
} | ||
|
||
@Override | ||
public void onSaveInstanceState(final Bundle outState) { | ||
super.onSaveInstanceState(outState); | ||
mDelegate.onSaveInstanceState_afterSuper(outState); | ||
} | ||
|
||
@Override | ||
public void onStart() { | ||
super.onStart(); | ||
mDelegate.onStart_afterSuper(); | ||
} | ||
|
||
@Override | ||
public void onStop() { | ||
mDelegate.onStop_beforeSuper(); | ||
super.onStop(); | ||
} | ||
|
||
@Override | ||
public boolean postToMessageQueue(final Runnable runnable) { | ||
return getFragment().getActivity().getWindow().getDecorView().post(runnable); | ||
} | ||
|
||
/** | ||
* the default implementation assumes that the fragment is the view and implements the {@link | ||
* TiView} interface. Override this method for a different behaviour. | ||
* | ||
* @return the object implementing the TiView interface | ||
*/ | ||
@NonNull | ||
public V provideView() { | ||
|
||
final Class<?> foundViewInterface = AnnotationUtil | ||
.getInterfaceOfClassExtendingGivenInterface(getFragment().getClass(), TiView.class); | ||
|
||
if (foundViewInterface == null) { | ||
throw new IllegalArgumentException( | ||
"This Fragment doesn't implement a TiView interface. " | ||
+ "This is the default behaviour. Override provideView() to explicitly change this."); | ||
} else { | ||
if (foundViewInterface.getSimpleName().equals("TiView")) { | ||
throw new IllegalArgumentException( | ||
"extending TiView doesn't make sense, it's an empty interface." | ||
+ " This is the default behaviour. Override provideView() to explicitly change this."); | ||
} else { | ||
// assume that the fragment itself is the view and implements the TiView interface | ||
//noinspection unchecked | ||
return (V) getFragment(); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void setFragmentRetainInstance(final boolean retain) { | ||
setRetainInstance(retain); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
String presenter = mDelegate.getPresenter() == null ? "null" : | ||
mDelegate.getPresenter().getClass().getSimpleName() | ||
+ "@" + Integer.toHexString(mDelegate.getPresenter().hashCode()); | ||
|
||
return getClass().getSimpleName() | ||
+ ":" + TiFragment.class.getSimpleName() | ||
+ "@" + Integer.toHexString(hashCode()) | ||
+ "{presenter=" + presenter + "}"; | ||
} | ||
|
||
@Override | ||
protected void onAddedToDelegate() { | ||
super.onAddedToDelegate(); | ||
TAG = getClass().getSimpleName() | ||
+ ":" + TiFragment.class.getSimpleName() | ||
+ "@" + Integer.toHexString(this.hashCode()) | ||
+ ":" + getOriginal().getClass().getSimpleName() | ||
+ "@" + Integer.toHexString(getOriginal().hashCode()); | ||
} | ||
|
||
@Override | ||
protected void onRemovedFromDelegated() { | ||
super.onRemovedFromDelegated(); | ||
TAG = getClass().getSimpleName() | ||
+ ":" + TiFragment.class.getSimpleName() | ||
+ "@" + Integer.toHexString(this.hashCode()); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
getFragment.setRetainInstance(retain)
thx @mayankdbit