0

I have a web page with image and some text, image is having parallax effect. when i am loading the web page in a web view which is inside a scroll view, the parallax effect is not working. Scroll view also have recycler view along with web view. How to achieve the parallax effect in web page as well as seamless scroll for the whole page?

This video have the page i have developed with web view inside scroll view

This video is the demo screen with only web view, just to test the parallax in the web page

Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parent_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white">

    <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/news_detail_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <WebView
                android:id="@+id/web_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <RelativeLayout
                android:id="@+id/related"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone">

                <View
                    android:id="@+id/view"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/list_item_divider_height"
                    android:background="#dedede"
                    android:visibility="visible" />

                <TextView
                    android:id="@+id/related_title"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/view"
                    android:layout_margin="@dimen/main_margin"
                    android:text="@string/related_news"
                    android:textColor="@android:color/black"
                    android:textSize="@dimen/list_item_title"
                    android:textStyle="bold"
                    android:visibility="visible" />

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/related_article"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/related_title"
                    android:layout_marginLeft="8dp"
                    android:layout_marginRight="8dp"
                    android:visibility="visible" />
            </RelativeLayout>

            <RelativeLayout
                android:id="@+id/recommendation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone">

                <View
                    android:id="@+id/recommendation_seperator"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/list_item_divider_height"
                    android:background="#dedede"
                    android:visibility="visible" />

                <TextView
                    android:id="@+id/recommendation_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="@dimen/main_margin"
                    android:text="Sponsored Stories"
                    android:textColor="@android:color/black"
                    android:textSize="@dimen/list_item_title"
                    android:textStyle="bold" />

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_margin="@dimen/main_margin"
                    android:orientation="horizontal">

                    <TextView
                        android:id="@+id/drawer_title_view"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerVertical="true"
                        android:layout_gravity="center"
                        android:text="Recommended by "
                        android:textColor="@color/black_semi_trans"
                        android:textSize="12dp"
                        android:textStyle="bold" />

                    <ImageView
                        android:layout_width="24dp"
                        android:layout_height="24dp"
                        android:src="@drawable/ic_recommendation" />
                </LinearLayout>

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/recommendation_view"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/recommendation_title" />
            </RelativeLayout>

        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />
</RelativeLayout>

Java Class

   public class NewsDetailFragment extends Fragment implements ViewModel.ResponseListener<News>, RecyclerViewEvents.Listener<Object>,
        View.OnKeyListener, RecommendationsListener {

    private List<NewsItem> relatedList = new ArrayList<>();
    private RelatedArticleListAdapter relatedAdapter;
    private String url;
    private ClickEvents.ListItemListener listItemListener;
    private WebView webView;
    private ProgressBar progressBar;
    private boolean isWebViewPaused;
    private List<OBRecommendation> outbrainList = new ArrayList();
    private OutbrainAdapter outbrainAdapter;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        listItemListener = (ClickEvents.ListItemListener) activity;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        url = getArguments().getString(Constants.BundleKeys.URL);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate((Network.isConnected(getActivity())) ? R.layout.fragment_news_detail : R.layout.fragment_news_detail_offline, container, false);
        progressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
        webView = (WebView) view.findViewById(R.id.web_view);
        webView.setHorizontalScrollBarEnabled(false);
        webView.getSettings().setAppCacheEnabled(false);
        webView.setScrollBarStyle(WebView.SCROLLBARS_INSIDE_INSET);
        webView.setVerticalScrollBarEnabled(false);
        webView.setOnKeyListener(this);
        webView.getSettings().setJavaScriptEnabled(true);
        int fontSize = PreferenceManager.getsInstance(getActivity()).getSharedPrefs().getInt(PreferenceManager.PreferenceKeys.SETTINGS_CURRENT_FONT_SIZE, -1);
        switch (fontSize) {
            case 0: //LARGE
                webView.getSettings().setTextZoom(160);
                break;
            case 1: // MEDIUM
                webView.getSettings().setTextZoom(130);
                break;
            case 2: //NORMAL
                webView.getSettings().setTextZoom(100);
                break;
            case 3: //SMALL
                webView.getSettings().setTextZoom(70);
                break;
            default:
                webView.getSettings().setTextZoom(100);
        }

        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (Network.isConnected(getActivity())) {
            RecyclerView relatedRecyclerView = (RecyclerView) getView().findViewById(R.id.related_article);
            RecyclerView recommendationRecyclerView = (RecyclerView) getView().findViewById(R.id.recommendation_view);
            RelativeLayout recommendationLayout = (RelativeLayout) getView().findViewById(R.id.recommendation);
            RelativeLayout relatedLayout = (RelativeLayout) getView().findViewById(R.id.related);

            webView.setWebViewClient(new WebClient(progressBar, recommendationLayout, relatedLayout));
            relatedRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
            relatedRecyclerView.setAdapter(relatedAdapter = new RelatedArticleListAdapter(getActivity(), relatedList, this));

            OBRequest request = new OBRequest(url, getResources().getString(R.string.outbrain_widget));
            Outbrain.fetchRecommendations(request, this);
            GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);
            recommendationRecyclerView.setLayoutManager(layoutManager);
            outbrainAdapter = new OutbrainAdapter(getActivity(), outbrainList, this);
            recommendationRecyclerView.setAdapter(outbrainAdapter);

            webView.loadUrl(url);
            String keywords = getArguments().getString(Constants.BundleKeys.KEYWORDS);

            if (keywords != null) {
                String newsId = getArguments().getString(Constants.BundleKeys.NEWS_ID);
                String url = ConfigManager.getsInstance().getURL(Constants.CustomApiType.RELATED_NEWS);
                StringBuilder builder = new StringBuilder(url).append("&").append(APIService.QueryKeys.EXCLUDE_ID)
                        .append("=").append(newsId)
                        .append("&").append(APIService.QueryKeys.ALL_FIELDS).append("=")
                        .append(keywords);
                NewsViewModel newsViewModel = new NewsViewModel(getActivity(), this, builder.toString());
                newsViewModel.downloadRelatedNews();
            }
        } else {
            webView.setWebViewClient(new WebClient(progressBar));
            downloadCachedHTML(url);
        }

    }

    private void downloadCachedHTML(String url) {
        boolean isBookMarkNews = getArguments().getBoolean(Constants.BundleKeys.IS_BOOKMARK, false);
        HTMLClient client = HTMLClientFactory.create(getActivity(), isBookMarkNews ? CacheInfo.BOOKMARK_NEWS : CacheInfo.NEWS_DETAIL);
        HTMLAPIService apiService = client.getAPIService(HTMLAPIService.class);
        Call<String> call = apiService.downloadHtml(url);
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, retrofit2.Response<String> response) {
                if (getActivity() == null)
                    return;
                progressBar.setVisibility(View.GONE);
                if (response.body() != null) {
                    webView.loadDataWithBaseURL("", response.body(), "text/html", "utf-8", null);
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                progressBar.setVisibility(View.GONE);
            }
        });
    }

    @Override
    public void onItemClick(Object item, View v, int position) {
        if (item instanceof NewsItem) {
            News news = new News();
            news.newsList = relatedList;
            listItemListener.onNewsListItemClick(news, position, "",  false);
        }
        if (item instanceof OBRecommendation)
            listItemListener.onRecommendationItemClick(((OBRecommendation) item).getUrl());

    }

    @Override
    public void onResponse(News response) {
        relatedList.clear();
        relatedList.addAll(response.newsList);
        relatedAdapter.notifyDataSetChanged();
    }

    @Override
    public void onNextResponse(News response) {
    }

    @Override
    public void onNextError() {
    }

    @Override
    public void onError() {
        relatedList.clear();
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getActivity() == null)
            return;
        if (webView == null)
            return;
        if (isVisibleToUser)
            webView.onResume();
        else webView.onPause();

    }

    @Override
    public void onPause() {
        super.onPause();
        webView.onPause();
        isWebViewPaused = true;
    }

    @Override
    public void onResume() {
        super.onResume();
        if (isWebViewPaused) {
            webView.onResume();
            isWebViewPaused = false;
        }
    }

    @Override
    public void onOutbrainRecommendationsSuccess(OBRecommendationsResponse recommendations) {
        outbrainList.clear();
        outbrainList.addAll(recommendations.getAll());
        outbrainAdapter.notifyDataSetChanged();
    }

    @Override
    public void onOutbrainRecommendationsFailure(Exception ex) {
        outbrainList.clear();
    }


    private class WebClient extends WebViewClient {
        private final ProgressBar progressBar;
        private RelativeLayout recommendation;
        private RelativeLayout related;

        public WebClient(ProgressBar progressBar, RelativeLayout recommendation, RelativeLayout related) {
            this.progressBar = progressBar;
            this.recommendation = recommendation;
            this.related = related;

        }

        public WebClient(ProgressBar progressBar) {
            this.progressBar = progressBar;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            progressBar.setVisibility(View.VISIBLE);
            if (Network.isConnected(getActivity())) {
                recommendation.setVisibility(View.GONE);
                related.setVisibility(View.GONE);
            }
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            progressBar.setVisibility(View.GONE);
            if (Network.isConnected(getActivity())) {
                related.setVisibility(relatedList.isEmpty() ? View.GONE : View.VISIBLE);
                recommendation.setVisibility(outbrainList.isEmpty() ? View.GONE : View.VISIBLE);
            }
        }

        @SuppressWarnings("deprecation")
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            if (!Network.isConnected(getActivity())) {
                WebResourceResponse response = getResponse(url);
                return response == null ? super.shouldInterceptRequest(view, url) : response;
            }
            return super.shouldInterceptRequest(view, url);
        }

        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            if (!Network.isConnected(getActivity())) {
                String url = request.getUrl().toString();
                WebResourceResponse response = getResponse(url);
                return response == null ? super.shouldInterceptRequest(view, request) : response;

            }
            return super.shouldInterceptRequest(view, request);
        }

        @Nullable
        private WebResourceResponse getResponse(String url) {
            if (url.endsWith(".png") || url.endsWith(".jpg")) {
                boolean isBookMarkNews = getArguments().getBoolean(Constants.BundleKeys.IS_BOOKMARK, false);
                HTMLClient client = HTMLClientFactory.create(getActivity(), isBookMarkNews ? CacheInfo.BOOKMARK_NEWS : CacheInfo.NEWS_DETAIL);
                File cachedFile = new File(client.getImageDir() + File.separator + HTMLInterceptor.getFileName(url));
                if (cachedFile.exists()) {
                    try {
                        return new WebResourceResponse(
                                "image/*", "utf-8", new FileInputStream(cachedFile));
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            if (Network.isConnected(progressBar.getContext()))
                return false;
            else return true;
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return super.shouldOverrideUrlLoading(view, url);
        }
    }


    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            WebView webView = (WebView) v;
            switch (keyCode) {
                case KeyEvent.KEYCODE_BACK:
                    if (webView.canGoBack()) {
                        webView.goBack();
                        return true;
                    }
                    break;
            }
        }
        return false;

    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        webView.destroy();
    }
}
Community
  • 1
  • 1
Nitesh Mishra
  • 41
  • 1
  • 4
  • 12

0 Answers0