ChromeLikeTabSwitcher icon indicating copy to clipboard operation
ChromeLikeTabSwitcher copied to clipboard

[Discussion] Using this library together with WebViews

Open michael-rapp opened this issue 6 years ago • 7 comments

It seems like a lot of people try to use this library together with WebViews in order to implement custom web browsers. However, it seems to be non-trivial to properly use WebView's together with the library's recycling mechanism that reuses previously inflated views to display the contents of different tabs when they are not visible anymore. The following issues are related to this problem:

  • https://github.com/michael-rapp/ChromeLikeTabSwitcher/issues/5
  • https://github.com/michael-rapp/ChromeLikeTabSwitcher/issues/17
  • https://github.com/michael-rapp/ChromeLikeTabSwitcher/issues/18

I don't have enough experience with the WebView class to give good advices on this issue. I even hadn't WebViews in mind when I implemented this library. Therefore this issue is meant to be a platform for discussing this problem. It would be great, if those that are interested in using this library together with WebView's could share their experiences here. Even better, if someone would create a simple example project at Github different people would be able to enhance it, which will hopefully result in a satisfying solution to be used by everyone. I will do my best to comment on issues and give advices about how to use this library properly.

I think that the recycling mechanism of the library works great as it is and there is no need to add any workarounds to get it to work together with WebView's. Of course there is a chance that there might be any bugs related to it. If that's the case, I will do my best to fix them.

In my opinion the following things must be tackled:

  • It is necessary to save the state of a WebView in memory or on the local storage. This includes the visited URL, the history and the content of the displayed website.
  • If the WebView class does not provide a suitable way to store/restore its full state out of the box, it is necessary to implement this by ourselves.
  • For displaying the previews of tabs it might be helpful to display a "screenshot" of the website rather than actually using the WebView to render the website.
  • Frequently reloading the URL of the WebView is no option as this will result in a bad user experience due to the fact that network requests are time consuming.

I hope that some people will contribute to this issue and share their opinions and experiences in order to solve this problem.

michael-rapp avatar Jul 27 '18 13:07 michael-rapp

Hi ,

I have enough experience with webview and I can contribute to this issue and I really need to do that beacuse I developed a browser based on this library, just need to handle reload issue at various instant.

As per you mentioned recycling mechanism: " it seems to be non-trivial to properly use WebView's together with the library's recycling mechanism that reuses previously inflated views to display the contents of different tabs when they are not visible anymore".

Can you tell me ? The classes name that responsible for recycler view bheaviour so that i can move forward to handle webview in this library.

anandmahesh avatar Jul 27 '18 18:07 anandmahesh

Recycling mechanism

The basic idea of the recycling mechanism is really simple:

  • Whenever the content of a tab becomes visible (either because it is selected and therefore shown fullscreen, or because it becomes visible while scrolling through the tabs) the view that is necessary to display the tab's content is added to the tab's container layout. This is achieved in one of the following ways:
  1. If no recyclable view are available, it is inflated from scratch using the onInflateView-method of your TabSwitcherDecorator-implementation. Afterwards the TabSwitcherDecorator's onShowView-method is invoked. It is meant to adjust the appearance of the inflated view depending on the tab it belongs to.
  2. If a recyclable view is available, the onInflateView-method is NOT called. Instead, the existing view is used. However, the onShowView-method is invoked in order to adjust the view to display the correct content. Implementing the onShowView-method to correctly is crucial to be sure that the correct content is displayed. This is because the recycled view is still in the same state as it was when it was used for the last time (probably it was used to display the content of another tab).
  • Once the content of a tab becomes invisible, the view that displays its content is removed from the tab's container layout. However it is retained in a cache and might be reused as described above. Only if the device runs out of memory the cached views are eventually destroyed.

Because of this mechanism it is not necessary to inflate an individual view for each tab. As there is no chance that all tabs are visible at the same time, the number of inflated views is kept to a minimum. This enables to use a large number of tabs without occupying too much memory. Furthermore, inflating views is relatively time consuming and therefore it is desirable to reuse existing views to achieve a better performance and smother scrolling behavior.

The mechanism I described above is very similar to how RecyclerViews work in Android. When using a RecyclerView, the views that are used to display individual list items are also reused internally. The TabSwitcherDecorator's onInflateView-method corresponds to the onCreateViewHolder-method of the class RecyclerView.Adapter. The onShowView-method corresponds to the onBindViewHolder-method. I think it helps to think about the library's TabSwitcher as a RecyclerView, where the individual tabs behave similar as list items.

Restore mechanism

There is also a built-in mechanism to save the state of a tab when its content is removed and to restore it later when the tab becomes visible again:

  • When the content of a tab is removed, the onSaveInstanceState-method of your TabSwitcherDecorator is called. It allows to store the state in a Bundle.
  • When the tab's content becomes visible again, the onShowView-method is called as described above (regardless of a recycled view is used or not). If any previously saved state is available, the corresponding Bundle is passed as a method parameter.

This behavior is similar to restoring the state of a Fragment, where the state can be stored in the onSaveInstanceState-method and the saved state is passed to the onCreateView-method when the fragment's content is recreated.

Implementation details

For recycling views this library uses an instance of the class AbstractViewRecycler. It is responsible for deciding if any recyclable views are available, or if it is necessary to inflate new views. An instance of the class ContentRecyclerAdapter is attached to it. It can be seen as a connection between the ViewRecycler and your custom TabSwitcherDecorator-implementation. It invokes the TabSwitcherDecorator's method such as onInflateView, onShowView and onSaveInstanceState and manages the saved states of all tabs.

michael-rapp avatar Jul 27 '18 20:07 michael-rapp

@anandmahesh Are you interested in creating a sample project that implements a really simple demonstration of how to use the library together with WebViews? Maybe this would help you to figure out how things need to be implemented without dealing with the complexity of a real app. I would contribute to it if necessary and it could be used as a reference for other developers.

michael-rapp avatar Jul 27 '18 20:07 michael-rapp

Yes, I am interested in creating a sample project to demonstrate the working of web views with this library and thanks for a brief overview of classes and mechanism. Give me some time, I will get back to you after creating a demo project.

anandmahesh avatar Jul 28 '18 06:07 anandmahesh

@anandmahesh Did you make any progress on this issue?

michael-rapp avatar Sep 05 '18 00:09 michael-rapp

Hello. WebView cannot save full state. Using this library is not possible with WebView without disable recycle. It would be nice to have such an opportunity.

BoldakovAlex avatar Oct 19 '18 19:10 BoldakovAlex

Hey, I 'm using this library in my project with webview but have blinking issue as well as layout inflate issue. Basically I couldn't use webview in my main activity layout. I am to use switcher view in my main layout then inflate my desired view using onFlateView() method of Decorator class where I also have a frame layout and for every new Tab I create a object of Webview and attach this webview in frame layout.

z4zzaman avatar Feb 12 '19 16:02 z4zzaman