Initial slow move toward MVP pattern
This commit is contained in:
parent
0e211ebf85
commit
65c2c9c461
@ -90,6 +90,8 @@ import javax.inject.Inject;
|
||||
|
||||
import acr.browser.lightning.R;
|
||||
import acr.browser.lightning.app.BrowserApp;
|
||||
import acr.browser.lightning.browser.BrowserPresenter;
|
||||
import acr.browser.lightning.browser.BrowserView;
|
||||
import acr.browser.lightning.bus.BookmarkEvents;
|
||||
import acr.browser.lightning.bus.BrowserEvents;
|
||||
import acr.browser.lightning.bus.NavigationEvents;
|
||||
@ -119,7 +121,7 @@ import acr.browser.lightning.view.LightningView;
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public abstract class BrowserActivity extends ThemableBrowserActivity implements UIController, OnClickListener, OnLongClickListener {
|
||||
public abstract class BrowserActivity extends ThemableBrowserActivity implements BrowserView, UIController, OnClickListener, OnLongClickListener {
|
||||
|
||||
// Static Layout
|
||||
@Bind(R.id.drawer_layout)
|
||||
@ -195,6 +197,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
private Drawable mDeleteIcon, mRefreshIcon, mClearIcon, mIcon;
|
||||
private DrawerArrowDrawable mArrowDrawable;
|
||||
|
||||
private BrowserPresenter mPresenter;
|
||||
|
||||
// Proxy
|
||||
@Inject ProxyUtils mProxyUtils;
|
||||
|
||||
@ -221,6 +225,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
BrowserApp.getAppComponent().inject(this);
|
||||
setContentView(R.layout.activity_main);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
mPresenter = new BrowserPresenter(this);
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
@ -828,6 +835,102 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private View mCurrentView;
|
||||
|
||||
@Override
|
||||
public void removeTabView() {
|
||||
|
||||
// Set the background color so the color mode color doesn't show through
|
||||
mBrowserFrame.setBackgroundColor(mBackgroundColor);
|
||||
|
||||
mIsNewIntent = false;
|
||||
|
||||
mBrowserFrame.removeAllViews();
|
||||
|
||||
removeViewFromParent(mCurrentView);
|
||||
|
||||
if (mFullScreen) {
|
||||
// mToolbarLayout has already been removed
|
||||
mBrowserFrame.addView(mToolbarLayout);
|
||||
mToolbarLayout.bringToFront();
|
||||
mToolbarLayout.setTranslationY(0);
|
||||
}
|
||||
|
||||
mCurrentView = null;
|
||||
|
||||
// Use a delayed handler to make the transition smooth
|
||||
// otherwise it will get caught up with the showTab code
|
||||
// and cause a janky motion
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDrawerLayout.closeDrawers();
|
||||
}
|
||||
}, 200);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTabView(@NonNull View view) {
|
||||
if (mCurrentView == view) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the background color so the color mode color doesn't show through
|
||||
mBrowserFrame.setBackgroundColor(mBackgroundColor);
|
||||
|
||||
mIsNewIntent = false;
|
||||
|
||||
final float translation = mToolbarLayout.getTranslationY();
|
||||
mBrowserFrame.removeAllViews();
|
||||
|
||||
removeViewFromParent(view);
|
||||
removeViewFromParent(mCurrentView);
|
||||
|
||||
mBrowserFrame.addView(view, MATCH_PARENT);
|
||||
|
||||
view.requestFocus();
|
||||
|
||||
if (mFullScreen) {
|
||||
// mToolbarLayout has already been removed
|
||||
mBrowserFrame.addView(mToolbarLayout);
|
||||
mToolbarLayout.bringToFront();
|
||||
Log.d(Constants.TAG, "Move view to browser frame");
|
||||
int height = mToolbarLayout.getHeight();
|
||||
if (height == 0) {
|
||||
mToolbarLayout.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
height = mToolbarLayout.getMeasuredHeight();
|
||||
}
|
||||
view.setTranslationY(translation + height);
|
||||
mToolbarLayout.setTranslationY(translation);
|
||||
} else {
|
||||
view.setTranslationY(0);
|
||||
}
|
||||
|
||||
mCurrentView = view;
|
||||
|
||||
showActionBar();
|
||||
|
||||
// Use a delayed handler to make the transition smooth
|
||||
// otherwise it will get caught up with the showTab code
|
||||
// and cause a janky motion
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDrawerLayout.closeDrawers();
|
||||
}
|
||||
}, 200);
|
||||
|
||||
// new Handler().postDelayed(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// Remove browser frame background to reduce overdraw
|
||||
//TODO evaluate performance
|
||||
// mBrowserFrame.setBackgroundColor(Color.TRANSPARENT);
|
||||
// }
|
||||
// }, 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* displays the WebView contained in the LightningView Also handles the
|
||||
* removal of previous views
|
||||
@ -837,11 +940,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
private synchronized void showTab(final int position) {
|
||||
final LightningView currentView = mTabsManager.getCurrentTab();
|
||||
final LightningView newView = mTabsManager.switchToTab(position);
|
||||
switchTabs(currentView, newView);
|
||||
//TODO move this code elsewhere
|
||||
// switchTabs(currentView, newView);
|
||||
}
|
||||
|
||||
// This is commodity to breack the flow between regular tab management and the CLIQZ's search
|
||||
// interface.
|
||||
// TODO remove all usages, switch to using the presenter instead
|
||||
@Deprecated
|
||||
private void switchTabs(final LightningView currentView, final LightningView newView) {
|
||||
final WebView newWebView = newView != null ? newView.getWebView() : null;
|
||||
if (newView == null || newWebView == null) {
|
||||
@ -912,7 +1018,10 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
|
||||
}
|
||||
|
||||
private static void removeViewFromParent(View view) {
|
||||
private static void removeViewFromParent(@Nullable View view) {
|
||||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
ViewGroup parent = ((ViewGroup) view.getParent());
|
||||
if (parent != null) {
|
||||
parent.removeView(view);
|
||||
@ -988,6 +1097,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
}
|
||||
}
|
||||
|
||||
// TODO move to presenter
|
||||
private synchronized boolean newTab(String url, boolean show) {
|
||||
// Limit number of tabs for limited version of app
|
||||
if (!Constants.FULL_VERSION && mTabsManager.size() >= 10) {
|
||||
@ -1018,6 +1128,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO move this to presenter
|
||||
private synchronized void deleteTab(int position) {
|
||||
final LightningView tabToDelete = mTabsManager.getTabAtPosition(position);
|
||||
|
||||
@ -1050,10 +1161,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
closeBrowser();
|
||||
return;
|
||||
} else if (afterTab != currentTab) {
|
||||
switchTabs(currentTab, afterTab);
|
||||
if (currentTab != null) {
|
||||
currentTab.pauseTimers();
|
||||
}
|
||||
//TODO remove this?
|
||||
// switchTabs(currentTab, afterTab);
|
||||
// if (currentTab != null) {
|
||||
// currentTab.pauseTimers();
|
||||
// }
|
||||
}
|
||||
|
||||
mEventBus.post(new BrowserEvents.TabsChanged());
|
||||
@ -1177,6 +1289,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Log.d(Constants.TAG, "onDestroy");
|
||||
|
||||
if (mPresenter != null) {
|
||||
mPresenter.destroy();
|
||||
}
|
||||
|
||||
if (mHistoryDatabase != null) {
|
||||
mHistoryDatabase.close();
|
||||
mHistoryDatabase = null;
|
||||
|
@ -45,9 +45,28 @@ public class TabsManager {
|
||||
@Inject Bus mEventBus;
|
||||
@Inject Application mApp;
|
||||
|
||||
@Nullable private TabChangeListener mListener;
|
||||
|
||||
public interface TabChangeListener {
|
||||
void tabChanged(LightningView newTab);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public TabsManager() {}
|
||||
|
||||
/**
|
||||
* Sets the {@link TabChangeListener} to a new
|
||||
* listener. Can be set to null if the caller
|
||||
* wishes to unregister the listener.
|
||||
*
|
||||
* @param listener the new listener to use or
|
||||
* null if the caller wishes to
|
||||
* unregister the listener.
|
||||
*/
|
||||
public void setTabChangeListener(@Nullable TabChangeListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores old tabs that were open before the browser
|
||||
* was closed. Handles the intent used to open the browser.
|
||||
@ -137,6 +156,7 @@ public class TabsManager {
|
||||
* released for garbage collection.
|
||||
*/
|
||||
public synchronized void shutdown() {
|
||||
sendTabChangedEvent(null);
|
||||
for (LightningView tab : mTabList) {
|
||||
tab.onDestroy();
|
||||
}
|
||||
@ -195,6 +215,7 @@ public class TabsManager {
|
||||
public synchronized LightningView newTab(@NonNull final Activity activity,
|
||||
@Nullable final String url,
|
||||
final boolean isIncognito) {
|
||||
Log.d(TAG, "New tab");
|
||||
final LightningView tab = new LightningView(activity, url, isIncognito);
|
||||
mTabList.add(tab);
|
||||
return tab;
|
||||
@ -227,6 +248,7 @@ public class TabsManager {
|
||||
* @param position the position of the tab to delete.
|
||||
*/
|
||||
public synchronized void deleteTab(int position) {
|
||||
Log.d(TAG, "Delete tab: " + position);
|
||||
final LightningView currentTab = getCurrentTab();
|
||||
int current = positionOf(currentTab);
|
||||
|
||||
@ -239,6 +261,7 @@ public class TabsManager {
|
||||
} else {
|
||||
mCurrentTab = getTabAtPosition(current - 1);
|
||||
}
|
||||
sendTabChangedEvent(mCurrentTab);
|
||||
removeTab(current);
|
||||
} else {
|
||||
removeTab(position);
|
||||
@ -330,16 +353,34 @@ public class TabsManager {
|
||||
*/
|
||||
@Nullable
|
||||
public synchronized LightningView switchToTab(final int position) {
|
||||
Log.d(TAG, "switch to tab: " + position);
|
||||
if (position < 0 || position >= mTabList.size()) {
|
||||
Log.e(TAG, "Returning a null LightningView requested for position: " + position);
|
||||
sendTabChangedEvent(null);
|
||||
return null;
|
||||
} else {
|
||||
final LightningView tab = mTabList.get(position);
|
||||
if (tab != null) {
|
||||
mCurrentTab = tab;
|
||||
}
|
||||
sendTabChangedEvent(tab);
|
||||
return tab;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the event that the current tab has changed to
|
||||
* a new tab to the {@link TabChangeListener} if it is
|
||||
* not null.
|
||||
*
|
||||
* @param newView the new tab that we have switcted to,
|
||||
* can be null if the last tab has been
|
||||
* deleted.
|
||||
*/
|
||||
private void sendTabChangedEvent(@Nullable LightningView newView) {
|
||||
if (mListener != null) {
|
||||
mListener.tabChanged(newView);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import acr.browser.lightning.activity.BrowserActivity;
|
||||
import acr.browser.lightning.activity.ReadingActivity;
|
||||
import acr.browser.lightning.activity.ThemableBrowserActivity;
|
||||
import acr.browser.lightning.activity.ThemableSettingsActivity;
|
||||
import acr.browser.lightning.browser.BrowserPresenter;
|
||||
import acr.browser.lightning.constant.StartPage;
|
||||
import acr.browser.lightning.dialog.LightningDialogBuilder;
|
||||
import acr.browser.lightning.download.LightningDownloadListener;
|
||||
@ -61,4 +62,6 @@ public interface AppComponent {
|
||||
|
||||
void inject(StartPage startPage);
|
||||
|
||||
void inject(BrowserPresenter presenter);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
package acr.browser.lightning.browser;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import acr.browser.lightning.activity.TabsManager;
|
||||
import acr.browser.lightning.activity.TabsManager.TabChangeListener;
|
||||
import acr.browser.lightning.app.BrowserApp;
|
||||
import acr.browser.lightning.view.LightningView;
|
||||
|
||||
/**
|
||||
* Presenter in charge of keeping track of
|
||||
* the current tab and setting the current tab
|
||||
* of the
|
||||
*/
|
||||
public class BrowserPresenter {
|
||||
|
||||
private static final String TAG = BrowserPresenter.class.getSimpleName();
|
||||
|
||||
@Inject TabsManager mTabsModel;
|
||||
|
||||
@NonNull private BrowserView mView;
|
||||
@Nullable private LightningView mCurrentTab;
|
||||
|
||||
private static class TabListener implements TabChangeListener {
|
||||
|
||||
private BrowserPresenter mPresenter;
|
||||
|
||||
public TabListener(@NonNull BrowserPresenter presenter) {
|
||||
mPresenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tabChanged(@Nullable LightningView newTab) {
|
||||
mPresenter.onTabChanged(newTab);
|
||||
}
|
||||
}
|
||||
|
||||
public BrowserPresenter(@NonNull BrowserView view) {
|
||||
BrowserApp.getAppComponent().inject(this);
|
||||
mView = view;
|
||||
mTabsModel.setTabChangeListener(new TabListener(this));
|
||||
}
|
||||
|
||||
private void onTabChanged(@Nullable LightningView newTab) {
|
||||
Log.d(TAG, "On tab changed");
|
||||
if (newTab == null) {
|
||||
mView.removeTabView();
|
||||
if (mCurrentTab != null) {
|
||||
mCurrentTab.pauseTimers();
|
||||
mCurrentTab.onDestroy();
|
||||
}
|
||||
} else {
|
||||
if (newTab.getWebView() == null) {
|
||||
mView.removeTabView();
|
||||
if (mCurrentTab != null) {
|
||||
mCurrentTab.pauseTimers();
|
||||
mCurrentTab.onDestroy();
|
||||
}
|
||||
} else {
|
||||
if (mCurrentTab != null) {
|
||||
mCurrentTab.onPause();
|
||||
mCurrentTab.setForegroundTab(false);
|
||||
}
|
||||
newTab.onResume();
|
||||
newTab.resumeTimers();
|
||||
newTab.setForegroundTab(true);
|
||||
mView.updateProgress(newTab.getProgress());
|
||||
mView.updateUrl(newTab.getUrl(), true);
|
||||
mView.setTabView(newTab.getWebView());
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentTab = newTab;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
mTabsModel.setTabChangeListener(null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package acr.browser.lightning.browser;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.View;
|
||||
|
||||
public interface BrowserView {
|
||||
|
||||
void setTabView(@NonNull View view);
|
||||
|
||||
void removeTabView();
|
||||
|
||||
void updateUrl(String url, boolean shortUrl);
|
||||
|
||||
void updateProgress(int progress);
|
||||
|
||||
}
|
@ -15,7 +15,6 @@ import android.support.annotation.AttrRes;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.ImageView;
|
||||
|
@ -82,6 +82,7 @@ public class UrlUtils {
|
||||
* URL. If false, invalid URLs will return null
|
||||
* @return Original or modified URL
|
||||
*/
|
||||
@NonNull
|
||||
public static String smartUrlFilter(@NonNull String url, boolean canBeSearch, String searchUrl) {
|
||||
String inUrl = url.trim();
|
||||
boolean hasSpace = inUrl.indexOf(' ') != -1;
|
||||
@ -107,7 +108,7 @@ public class UrlUtils {
|
||||
return URLUtil.composeSearchUrl(inUrl,
|
||||
searchUrl, QUERY_PLACE_HOLDER);
|
||||
}
|
||||
return null;
|
||||
return "";
|
||||
}
|
||||
|
||||
/* package */
|
||||
|
Loading…
x
Reference in New Issue
Block a user