com.shaweibo.biu.ui.timeline.StatusDetailActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.shaweibo.biu.ui.timeline.StatusDetailActivity.java

Source

/*
 * 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);

        }

    }

}