/*
* Copyright 2014 Soichiro Kashima
*
* 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 com.shaweibo.biu.ui.timeline;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.shaweibo.biu.R;
import com.shaweibo.biu.Utils.DeviceUtil;
import com.shaweibo.biu.Utils.SpannableStringUtils;
import com.shaweibo.biu.Utils.StatusTimeUtils;
import com.shaweibo.biu.Utils.Utility;
import com.shaweibo.biu.adapter.comments.StatusComentAdapter;
import com.shaweibo.biu.dao.favo.FavoDao;
import com.shaweibo.biu.global.Constants;
import com.shaweibo.biu.global.MyApplication;
import com.shaweibo.biu.model.MessageModel;
import com.shaweibo.biu.model.PicSize;
import com.shaweibo.biu.ui.comments.StatusCommentFragment;
import com.shaweibo.biu.ui.common.BaseActivity;
import com.shaweibo.biu.ui.common.ViewPagerTabRecyclerViewFragment;
import com.shaweibo.biu.ui.picture.PicsActivity;
import com.shaweibo.biu.ui.post.PostNewCommentActivity;
import com.shaweibo.biu.ui.post.PostNewRepostActivity;
import com.shaweibo.biu.widget.FlowLayout;
import com.shaweibo.biu.widget.TagImageVIew;
import com.shaweibo.biu.widget.TextViewFixTouchConsume;
import com.github.ksoichiro.android.observablescrollview.CacheFragmentStatePagerAdapter;
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
import com.github.ksoichiro.android.observablescrollview.Scrollable;
import com.nineoldandroids.view.ViewHelper;
import com.nineoldandroids.view.ViewPropertyAnimator;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.InjectView;
/**
* This is an example of ViewPager + SlidingTab + ListView/ScrollView.
* This example shows how to handle scroll events for several different fragments.
* <p/>
* SlidingTabLayout and SlidingTabStrip are from google/iosched:
* https://github.com/google/iosched
*/
public class StatusDetailActivity extends BaseActivity implements ViewPagerTabRecyclerViewFragment.HeaderViewObserve ,StatusComentAdapter.HeaderViewTouchListener, View.OnClickListener {
public static final String EXT_WEIBO = "eta_weibo";
@InjectView(R.id.tv_time_source)
public TextView tv_time_source;
@InjectView(R.id.tv_username)
public TextView tv_username;
@InjectView(R.id.tv_content)
public TextViewFixTouchConsume tv_content;
@InjectView(R.id.ll_like)
public LinearLayout ll_like;
@InjectView(R.id.fl_images)
public FlowLayout fl_images;
@InjectView(R.id.iv_avatar)
public ImageView iv_avatar;
@InjectView(R.id.fl_images_repost)
public FlowLayout fl_images_repost;
@InjectView(R.id.tv_like_count)
TextView tv_like_count;
@InjectView(R.id.pager)
ViewPager mPager;
@InjectView(R.id.rl_repost)
View rl_repost;
// @InjectView(R.id.header)
// View mHeaderView;
@InjectView(R.id.header_toolbar)
View mToolbarView;
@InjectView(R.id.toolbar)
Toolbar toolbar;
@InjectView(R.id.sliding_tabs)
TabLayout mSlidingTabLayout;
@InjectView(R.id.tv_orignal_content)
public TextViewFixTouchConsume tv_orignal_content;
private NavigationAdapter mPagerAdapter;
public MessageModel mWeibo;
private int photoMargin;
private float imageMaxWidth;
private int mFlexibleSpaceHeight=0;
private int mTabHeight;
public static void start(Context context, MessageModel messageModel) {
Intent intent = new Intent(context, StatusDetailActivity.class);
intent.putExtra(EXT_WEIBO, messageModel);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_status_detail);
ButterKnife.inject(this);
if (savedInstanceState != null) {
mWeibo = savedInstanceState.getParcelable(EXT_WEIBO);
} else {
mWeibo = getIntent().getParcelableExtra(EXT_WEIBO);
}
mTabHeight = getResources().getDimensionPixelSize(R.dimen.tab_height);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mWeibo.span= SpannableStringUtils.getSpan(this, mWeibo, true);
photoMargin = getResources().getDimensionPixelSize(R.dimen.moment_photo_margin);
DisplayMetrics metrics = getResources().getDisplayMetrics();
float padding = getResources().getDimension(R.dimen.LargePadding);
imageMaxWidth = metrics.widthPixels - 2* padding;
initWeibo();
String[] titles=new String[]{getString(R.string.comment) + " ( " + Utility.getCountString(mWeibo.comments_count) + " ) ",
getString(R.string.repost) + " ( " + Utility.getCountString(mWeibo.reposts_count) + " ) "
};
mPagerAdapter = new NavigationAdapter(getSupportFragmentManager(), mWeibo,titles);
mPager.setAdapter(mPagerAdapter);
mSlidingTabLayout.setupWithViewPager(mPager);
// Initialize the first Fragment's state when layout is completed.
ScrollUtils.addOnGlobalLayoutListener(mSlidingTabLayout, new Runnable() {
@Override
public void run() {
translateTab(0, false);
}
});
}
/**
* Called by children Fragments when their scrollY are changed.
* They all call this method even when they are inactive
* but this Activity should listen only the active child,
* so each Fragments will pass themselves for Activity to check if they are active.
*
* @param scrollY scroll position of Scrollable
* @param s caller Scrollable view
*/
public void onScrollChanged(int scrollY, Scrollable s) {
if(mFlexibleSpaceHeight==0){
mFlexibleSpaceHeight=getHeadViewHeight();
}
Fragment fragment =
getCurrentFragment();
if (fragment == null) {
return;
}
View view = fragment.getView();
if (view == null) {
return;
}
Scrollable scrollable = (Scrollable) view.findViewById(R.id.scroll);
if (scrollable == null) {
return;
}
if (scrollable == s) {
// This method is called by not only the current fragment but also other fragments
// when their scrollY is changed.
// So we need to check the caller(S) is the current fragment.
int adjustedScrollY = Math.min(scrollY, mFlexibleSpaceHeight - mTabHeight);
translateTab(adjustedScrollY, false);
propagateScroll(adjustedScrollY);
}
}
private void propagateScroll(int scrollY) {
// Set scrollY for the fragments that are not created yet
mPagerAdapter.setScrollY(scrollY);
// Set scrollY for the active fragments
for (int i = 0; i < mPagerAdapter.getCount(); i++) {
// Skip current item
if (i == mPager.getCurrentItem()) {
continue;
}
// Skip destroyed or not created item
ViewPagerTabRecyclerViewFragment f =
(ViewPagerTabRecyclerViewFragment) mPagerAdapter.getItemAt(i);
if (f == null) {
continue;
}
View view = f.getView();
if (view == null) {
continue;
}
f.setScrollY(scrollY, mFlexibleSpaceHeight);
f.updateFlexibleSpace(scrollY);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_weibo_detail, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_favo:
FavoDao dao = new FavoDao(mWeibo.id,StatusDetailActivity.this);
dao.favo();
break;
case R.id.action_copy:
ClipboardManager c= (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
c.setText(tv_content.getText());
break;
case R.id.action_comment:
PostNewCommentActivity.start(this, mWeibo);
break;
case R.id.action_repost:
PostNewRepostActivity.start(this, mWeibo);
break;
case android.R.id.home:
onBackPressed();
break;
}
return super.onOptionsItemSelected(item);
}
private void translateTab(int scrollY, boolean animated) {
int flexibleSpaceImageHeight =getHeadViewHeight();
int tabHeight = getResources().getDimensionPixelSize(R.dimen.tab_height);
View imageView = findViewById(R.id.header_toolbar);
View overlayView = findViewById(R.id.overlay);
overlayView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,flexibleSpaceImageHeight));
// Translate overlay and image
float flexibleRange = flexibleSpaceImageHeight - getActionBarSize();
int minOverlayTransitionY = tabHeight - overlayView.getHeight();
ViewHelper.setTranslationY(overlayView, ScrollUtils.getFloat(-scrollY, minOverlayTransitionY, 0));
ViewHelper.setTranslationY(imageView, ScrollUtils.getFloat(-scrollY / 2, minOverlayTransitionY, 0));
// Change alpha of overlay
ViewHelper.setAlpha(overlayView, ScrollUtils.getFloat((float) scrollY / flexibleRange, 0, 1));
// Scale title text
// float scale = 1 + ScrollUtils.getFloat((flexibleRange - scrollY - tabHeight) / flexibleRange, 0, MAX_TEXT_SCALE_DELTA);
// setPivotXToTitle(titleView);
// ViewHelper.setPivotY(titleView, 0);
// ViewHelper.setScaleX(titleView, scale);
// ViewHelper.setScaleY(titleView, scale);
// Translate title text
// int maxTitleTranslationY = flexibleSpaceImageHeight - tabHeight - getActionBarSize();
// int titleTranslationY = maxTitleTranslationY - scrollY;
// ViewHelper.setTranslationY(titleView, titleTranslationY);
// If tabs are moving, cancel it to start a new animation.
ViewPropertyAnimator.animate(mSlidingTabLayout).cancel();
// Tabs will move between the top of the screen to the bottom of the image.
float translationY = ScrollUtils.getFloat(-scrollY + mFlexibleSpaceHeight - mTabHeight, 0, mFlexibleSpaceHeight - mTabHeight);
if (animated) {
// Animation will be invoked only when the current tab is changed.
ViewPropertyAnimator.animate(mSlidingTabLayout)
.translationY(translationY)
.setDuration(200)
.start();
} else {
// When Fragments' scroll, translate tabs immediately (without animation).
ViewHelper.setTranslationY(mSlidingTabLayout, translationY);
}
}
private Fragment getCurrentFragment() {
return mPagerAdapter.getItemAt(mPager.getCurrentItem());
}
private void initWeibo() {
tv_content.setText(mWeibo.span);
tv_content.setMovementMethod(TextViewFixTouchConsume.LocalLinkMovementMethod.getInstance());
tv_username.setText(mWeibo.user.name);
String url = mWeibo.user.avatar_large;
if (!url.equals(iv_avatar.getTag())) {
iv_avatar.setTag(url);
ImageLoader.getInstance().displayImage(url, iv_avatar, Constants.getAvatarOptions(mWeibo.user.getName().substring(0, 1)));
}
iv_avatar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UserHomeActivity.start(StatusDetailActivity.this
, mWeibo.user);
}
});
String source = TextUtils.isEmpty(mWeibo.source) ? "" : Utility.dealSourceString(mWeibo.source);
tv_time_source.setText(StatusTimeUtils.instance(this).buildTimeString(mWeibo.created_at) + " | " + source);
tv_like_count.setText(" " + Utility.getCountString(mWeibo.attitudes_count));
if(mWeibo.retweeted_status==null){
dealImageLayout(fl_images,imageMaxWidth,mWeibo);
rl_repost.setVisibility(View.GONE);
}
else {
fl_images.setVisibility(View.GONE);
mWeibo.origSpan=SpannableStringUtils.getOrigSpan(this,mWeibo.retweeted_status,true);
tv_orignal_content .setText(mWeibo.origSpan);
tv_orignal_content.setMovementMethod(TextViewFixTouchConsume.LocalLinkMovementMethod.getInstance());
dealImageLayout(fl_images_repost, imageMaxWidth, mWeibo.retweeted_status);
rl_repost.setOnClickListener(this);
}
}
@Override
public int getHeadViewHeight() {
if(mToolbarView!=null){
return mToolbarView.getHeight();
}
return 0;
}
@Override
public boolean onTouch(MotionEvent event) {
return mToolbarView.dispatchTouchEvent(event);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.rl_repost:
StatusDetailActivity.start(this,mWeibo.retweeted_status);
break;
}
}
/**
* This adapter provides two types of fragments as an example.
* {@linkplain #createItem(int)} should be modified if you use this example for your app.
*/
private static class NavigationAdapter extends CacheFragmentStatePagerAdapter {
private String[] TITLES ;
private int mScrollY;
private MessageModel msg;
public NavigationAdapter(FragmentManager fm,MessageModel msg ,String[] titles) {
super(fm);
this.msg=msg;
TITLES=titles;
}
public void setScrollY(int scrollY) {
mScrollY = scrollY;
}
@Override
protected Fragment createItem(int position) {
// Initialize fragments.
// Please be sure to pass scroll position to each fragments using setArguments
//
Fragment f =null;
final int pattern = position % 4;
switch (pattern) {
case 0: {
f =StatusCommentFragment.newInstance(msg.id);
if (0 < mScrollY) {
Bundle args = new Bundle();
args.putInt(ViewPagerTabRecyclerViewFragment.ARG_INITIAL_POSITION, 1);
f.setArguments(args);
}
break;
}
case 1: {
f = StatusRepostFragment.newInstance(msg.id);
if (0 < mScrollY) {
Bundle args = new Bundle();
args.putInt(ViewPagerTabRecyclerViewFragment.ARG_INITIAL_POSITION, 1);
f.setArguments(args);
}
break;
}
}
return f;
}
@Override
public int getCount() {
return TITLES.length;
}
@Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
}
private void dealImageLayout(FlowLayout flowLayout, float maxWidth ,final MessageModel msg) {
flowLayout.removeAllViews();
for (int i = 0; i < 9; i++) {
TagImageVIew imageView = new TagImageVIew(this);
imageView.setBackgroundColor(getResources().getColor(R.color.bg_list_press));
imageView.setVisibility(View.GONE);
imageView.setAdjustViewBounds(true);
flowLayout.addView(imageView);
}
List<MessageModel.PictureUrl> medias = msg.pic_urls;
if (medias != null && medias.size() > 0) {
// int size = 0;
int mediumSize = (int) ((maxWidth - photoMargin) / 2);
int smallSize = (int) ((maxWidth - 2 * photoMargin) / 3);
int count = medias.size();
for (int i = 0; i < count; i++) {
if (i > flowLayout.getChildCount() - 1) {
break;
}
final MessageModel.PictureUrl pictureUrl = medias.get(i);
String imgUrl = pictureUrl.getThumbnail();
TagImageVIew imageView = (TagImageVIew) flowLayout.getChildAt(i);
imageView.setMinimumHeight(smallSize);
imageView.setMinimumWidth(smallSize);
FlowLayout.LayoutParams param = new FlowLayout.LayoutParams(smallSize, smallSize);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
;
PicSize picSize = null;
switch (count) {
case 1:
imgUrl = pictureUrl.getMedium();
picSize = MyApplication.picSizeCache.get(imgUrl);
if (picSize != null) {
param = new FlowLayout.LayoutParams(picSize.getWidth(), picSize.getHeight());
} else {
param = new FlowLayout.LayoutParams(FlowLayout.LayoutParams.WRAP_CONTENT, FlowLayout.LayoutParams.WRAP_CONTENT);
}
imageView.setMaxHeight((int) maxWidth);
imageView.setMaxWidth((int) maxWidth);
break;
case 3:
case 6:
case 9:
param = new FlowLayout.LayoutParams(smallSize, smallSize);
break;
case 2:
case 4:
param = new FlowLayout.LayoutParams(mediumSize, mediumSize);
break;
case 5:
case 7:
if (1 < i && i < 5) {
param = new FlowLayout.LayoutParams(smallSize, smallSize);
} else {
param = new FlowLayout.LayoutParams(mediumSize, mediumSize);
}
break;
case 8:
if (2 < i && i < 5) {
param = new FlowLayout.LayoutParams(mediumSize, mediumSize);
} else {
param = new FlowLayout.LayoutParams(smallSize, smallSize);
}
break;
default:
break;
}
imageView.setVisibility(View.VISIBLE);
imageView.setLayoutParams(param);
if (pictureUrl.isGif()) {
imageView.setDrawTag(true);
}
final int index = i;
if (DeviceUtil.getNetworkType(this) == DeviceUtil.NetWorkType.wifi && !pictureUrl.isGif()) {
imgUrl = pictureUrl.getMedium();
}
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PicsActivity.start(StatusDetailActivity.this, msg, index);
}
});
if (!TextUtils.isEmpty(imgUrl) && !imgUrl.equals(imageView.getTag())) {
ImageLoadingListener imageLoadingListener = null;
if (count == 1 && picSize == null) {
imageLoadingListener = new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
int width = loadedImage.getWidth();
int height = loadedImage.getHeight();
ImageView imageView = (ImageView) view;
int singleImgMaxHeight = (int) (imageMaxWidth * 2 / 3);
if (height > singleImgMaxHeight) {
height = (int) singleImgMaxHeight;
//
}
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
FlowLayout.LayoutParams param = new FlowLayout.LayoutParams(width, height);
imageView.setLayoutParams(param);
imageView.setImageBitmap(loadedImage);
PicSize picSize = new PicSize();
picSize.setKey(imageUri);
picSize.setWidth(width);
picSize.setHeight(height);
MyApplication.picSizeCache.put(picSize.getKey(), picSize);
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
}
};
}
ImageLoader.getInstance().displayImage(imgUrl, imageView, Constants.timelineListOptions, imageLoadingListener);
imageView.setTag(imgUrl);
}
}
flowLayout.setVisibility(View.VISIBLE);
}
}
}