package io.hefuyi.zhihudaily.ui.fragment;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.Toast;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import butterknife.Bind;
import butterknife.ButterKnife;
import io.hefuyi.zhihudaily.DailyApplication;
import io.hefuyi.zhihudaily.R;
import io.hefuyi.zhihudaily.injector.component.ApplicationComponent;
import io.hefuyi.zhihudaily.injector.component.DaggerStoryComponent;
import io.hefuyi.zhihudaily.injector.component.StoryComponent;
import io.hefuyi.zhihudaily.injector.module.ActivityModule;
import io.hefuyi.zhihudaily.injector.module.StoryModule;
import io.hefuyi.zhihudaily.mvp.contract.StoryContract;
import io.hefuyi.zhihudaily.mvp.model.Editor;
import io.hefuyi.zhihudaily.mvp.model.Story;
import io.hefuyi.zhihudaily.util.IntentUtils;
import io.hefuyi.zhihudaily.util.ScrollPullDownHelper;
import io.hefuyi.zhihudaily.util.SharedPrefUtils;
import io.hefuyi.zhihudaily.util.WebUtils;
import io.hefuyi.zhihudaily.widget.AvatarsView;
import io.hefuyi.zhihudaily.widget.StoryHeaderView;
/**
* A simple {@link Fragment} subclass.
*/
public class StoryFragment extends Fragment implements StoryContract.View{
public static final String TAG = StoryFragment.class.getSimpleName();
@Inject
StoryContract.Presenter storyPresenter;
@Bind(R.id.progressBar)
ProgressBar progressBar;
@Bind((R.id.rl_container_header))
RelativeLayout rlStoryHeader;
@Bind(R.id.scrollView)
ScrollView scrollView;
@Bind(R.id.webViewContainer)
LinearLayout llWebViewContainer;
@Bind(R.id.avatarView)
AvatarsView avatarsView;
@Bind(R.id.spaceView)
View spaceView;
private Toolbar mActionBarToolbar;
private StoryHeaderView mStoryHeaderView;
private SoftReference<WebView> mWebViewSoftReference;
private String mStoryId;
private ScrollPullDownHelper mScrollPullDownHelper;
private Story mStory;
/*初始化相关*/
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
injectDependences();
storyPresenter.attachView(this);
setHasOptionsMenu(true);
if (getArguments() != null) {
mStoryId = getArguments().getString(IntentUtils.EXTRA_STORY_ID);
}
mScrollPullDownHelper = new ScrollPullDownHelper();
}
private void injectDependences() {
ApplicationComponent applicationComponent = ((DailyApplication) getActivity().getApplication()).getApplicationComponent();
StoryComponent storyComponent = DaggerStoryComponent.builder()
.applicationComponent(applicationComponent)
.activityModule(new ActivityModule(getActivity()))
.storyModule(new StoryModule())
.build();
storyComponent.inject(this);
}
/*初始化相关*/
/*view接口*/
@Override
public void showStory(final Story story) {
Runnable runnable = new Runnable() {
@Override
public void run() {
if (story == null) {
return;
} else {
mStory = story;
bindData(story);
}
}
};
getActivity().runOnUiThread(runnable);
}
@Override
public void showError() {
Runnable runnable = new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "refresh error", Toast.LENGTH_SHORT).show();
}
};
getActivity().runOnUiThread(runnable);
}
@Override
public void showProgressBar() {
Runnable runnable = new Runnable() {
@Override
public void run() {
progressBar.setVisibility(View.VISIBLE);
}
};
getActivity().runOnUiThread(runnable);
}
@Override
public void hideProgressBar() {
Runnable runnable = new Runnable() {
@Override
public void run() {
progressBar.setVisibility(View.GONE);
}
};
getActivity().runOnUiThread(runnable);
}
/*view接口*/
/*普通逻辑*/
public static StoryFragment newInstance(String storyId) {
StoryFragment fragment = new StoryFragment();
Bundle bundle = new Bundle();
bundle.putString(IntentUtils.EXTRA_STORY_ID, storyId);
fragment.setArguments(bundle);
return fragment;
}
private boolean isWebViewOK() {
return mWebViewSoftReference != null && mWebViewSoftReference.get() != null;
}
private void bindData(Story story) {
boolean hasImage = !TextUtils.isEmpty(story.getImage());
bindHeaderView(hasImage);
bindAvatarsView();
bindWebView(hasImage);
}
private void bindHeaderView(boolean hasImage) {
if (hasImage) {
if (mActionBarToolbar != null) {
mActionBarToolbar.getBackground().mutate().setAlpha(0);
}
spaceView.setVisibility(View.VISIBLE);
rlStoryHeader.addView(mStoryHeaderView);
mStoryHeaderView.bindData(mStory.getTitle(), mStory.getImageSource(), mStory.getImage());
} else {
spaceView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
mActionBarToolbar.getHeight()));
}
}
private void bindAvatarsView() {
List<Editor> editors = mStory.getRecommenders();
if (editors != null && editors.size() > 0) {
avatarsView.setVisibility(View.VISIBLE);
List<String> avatars = new ArrayList<>(editors.size());
for (Editor editor : editors) {
avatars.add(editor.getAvatar());
}
avatarsView.bindData(getString(R.string.avatar_title_referee), avatars);
} else {
avatarsView.setVisibility(View.GONE);
}
}
private void bindWebView(boolean hasImage) {
if (TextUtils.isEmpty(mStory.getBody())) {
WebSettings settings = mWebViewSoftReference.get().getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setAppCacheEnabled(true);
mWebViewSoftReference.get().setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
mWebViewSoftReference.get().loadUrl(mStory.getShareUrl());
} else {
boolean isNightMode = SharedPrefUtils.isNightMode(getContext());
String data = WebUtils.buildHtmlWithCss(mStory.getBody(), mStory.getCssList(), isNightMode);
mWebViewSoftReference.get().loadDataWithBaseURL(WebUtils.BASE_URL, data, WebUtils.MIME_TYPE, WebUtils.ENCODING, WebUtils.FAIL_URL);
if (hasImage) {
addScrollListener();
}
}
}
private void addScrollListener() {
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
if (!isAdded()) {
return;
}
changeHeaderPosition();
changeToolbarAlpha();
}
});
}
private void changeHeaderPosition() {
int scrollY = scrollView.getScrollY();
int headerScrollY = (scrollY > 0) ? (scrollY / 2) : 0;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
mStoryHeaderView.setScrollY(headerScrollY);
mStoryHeaderView.requestLayout();
}
}
/**
* 1.如果滚动量小于图片和toolbar的差值,设置toolbar透明度,坐标为0,直接返回
* 2.如果滚动两大于差值,则开始修改toolbar的坐标,y坐标为滚动量的1中差值的差值
*/
private void changeToolbarAlpha() {
int scrollY = scrollView.getScrollY();
int storyHeaderViewHeight = getStoryHeaderViewHeight();
float toolbarHeight = mActionBarToolbar.getHeight();
float contentHeight = storyHeaderViewHeight - toolbarHeight;
float ratio = Math.min(scrollY / contentHeight, 1.0f);
mActionBarToolbar.getBackground().mutate().setAlpha((int) (ratio * 0xFF));
if (scrollY <= contentHeight) {
mActionBarToolbar.setY(0f);
return;
}
boolean isPullingDown = mScrollPullDownHelper.onScrollChange(scrollY);
float toolBarPositionY = isPullingDown ? 0 : (contentHeight - scrollY);
mActionBarToolbar.setY(toolBarPositionY);
}
private int getStoryHeaderViewHeight() {
return getResources().getDimensionPixelSize(R.dimen.view_header_story_height);
}
public void setToolBar(Toolbar toolbar) {
this.mActionBarToolbar = toolbar;
}
/*普通逻辑*/
/*生命周期回调*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mStoryHeaderView = StoryHeaderView.newInstance(container);
mWebViewSoftReference = new SoftReference<>(new WebView(getActivity()));
if (isWebViewOK()) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams
(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mWebViewSoftReference.get().setLayoutParams(layoutParams);
}
return inflater.inflate(R.layout.fragment_story, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
//去除滑动到底部的蓝色阴影
scrollView.setOverScrollMode(ScrollView.OVER_SCROLL_NEVER);
if (isWebViewOK()) {
llWebViewContainer.addView(mWebViewSoftReference.get());
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
storyPresenter.refresh(mStoryId);
}
@Override
public void onResume() {
super.onResume();
if (isWebViewOK()) {
mWebViewSoftReference.get().onResume();
}
}
@Override
public void onPause() {
super.onPause();
if (isWebViewOK()) {
mWebViewSoftReference.get().onPause();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (isWebViewOK()) {
mWebViewSoftReference.get().removeAllViews();
mWebViewSoftReference.get().destroy();
llWebViewContainer.removeView(mWebViewSoftReference.get());
mWebViewSoftReference = null;
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_story, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_share) {
if (mStory != null) {
IntentUtils.share(getActivity(), mStory);
}
}
return super.onOptionsItemSelected(item);
}
/*生命周期回调*/
}