org.catnut.plugin.zhihu.ZhihuItemFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.catnut.plugin.zhihu.ZhihuItemFragment.java

Source

/*
 * The MIT License (MIT)
 * Copyright (c) 2014 longkai
 * The software shall be used for good, not evil.
 */
package org.catnut.plugin.zhihu;

import android.app.Activity;
import android.app.Fragment;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.widget.SwipeRefreshLayout;
import android.text.Html;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.method.LinkMovementMethod;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.catnut.R;
import org.catnut.core.CatnutApp;
import org.catnut.core.CatnutProvider;
import org.catnut.fragment.GalleryPagerFragment;
import org.catnut.ui.SingleFragmentActivity;
import org.catnut.util.CatnutUtils;
import org.catnut.util.ColorSwicher;
import org.catnut.util.Constants;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ?
 *
 * @author longkai
 */
public class ZhihuItemFragment extends Fragment
        implements View.OnClickListener, SwipeRefreshLayout.OnRefreshListener {
    public static final String TAG = ZhihuItemFragment.class.getSimpleName();

    private static final String[] PROJECTION = new String[] { Zhihu.QUESTION_ID, Zhihu.ANSWER, Zhihu.DESCRIPTION,
            Zhihu.TITLE, Zhihu.LAST_ALTER_DATE, Zhihu.NICK, };

    public static final Pattern HTML_IMG = Pattern.compile("<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>");

    private static final int ACTION_VIEW_ON_WEB = 1;
    private static final int ACTION_VIEW_ALL_ON_WEB = 2;

    private Handler mHandler = new Handler();

    private SwipeRefreshLayout mSwipeRefreshLayout;

    private long mAnswerId;
    private long mQuestionId;

    private ArrayList<Uri> mImageUrls;

    public static ZhihuItemFragment getFragment(long id) {
        Bundle args = new Bundle();
        args.putLong(Constants.ID, id);
        ZhihuItemFragment fragment = new ZhihuItemFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mAnswerId = getArguments().getLong(Constants.ID);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.zhihu_item, container, false);

        mSwipeRefreshLayout = (SwipeRefreshLayout) view;
        ColorSwicher.injectColor(mSwipeRefreshLayout);
        mSwipeRefreshLayout.setOnRefreshListener(this);
        return view;
    }

    @Override
    public void onViewCreated(final View view, final Bundle savedInstanceState) {
        final TextView title = (TextView) view.findViewById(android.R.id.title);
        final TextView author = (TextView) view.findViewById(R.id.author);
        final TextView lastAlterDate = (TextView) view.findViewById(R.id.last_alter_date);

        registerForContextMenu(title);
        title.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getActivity().openContextMenu(title);
            }
        });

        (new Thread(new Runnable() {
            @Override
            public void run() {
                Cursor cursor = getActivity().getContentResolver().query(CatnutProvider.parse(Zhihu.MULTIPLE),
                        PROJECTION, Zhihu.ANSWER_ID + "=" + mAnswerId, null, null);
                if (cursor.moveToNext()) {
                    mQuestionId = cursor.getLong(cursor.getColumnIndex(Zhihu.QUESTION_ID));
                    final String _title = cursor.getString(cursor.getColumnIndex(Zhihu.TITLE));
                    final String _question = cursor.getString(cursor.getColumnIndex(Zhihu.DESCRIPTION));
                    final String _nick = cursor.getString(cursor.getColumnIndex(Zhihu.NICK));
                    final String _content = cursor.getString(cursor.getColumnIndex(Zhihu.ANSWER));
                    final long _lastAlterDate = cursor.getLong(cursor.getColumnIndex(Zhihu.LAST_ALTER_DATE));
                    cursor.close();

                    // answer
                    Matcher matcher = HTML_IMG.matcher(_content);
                    final List<String> contentSegment = new ArrayList<String>();
                    processText(_content, matcher, contentSegment);

                    // question
                    matcher = HTML_IMG.matcher(_question);
                    final List<String> questionSegment = new ArrayList<String>();
                    processText(_question, matcher, questionSegment);
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                            title.setText(_title);
                            getActivity().getActionBar().setSubtitle(_title);

                            // ???
                            int l = contentSegment.size() > 1 ? contentSegment.size() >> 1 : 0;
                            l += questionSegment.size() > 1 ? questionSegment.size() >> 1 : 0;

                            if (l > 0) {
                                mImageUrls = new ArrayList<Uri>(l);
                            }

                            // ?
                            boolean useCachedImg = CatnutApp.getBoolean(R.string.pref_enable_cache_zhihu_images,
                                    R.bool.default_plugin_status);

                            l = 0; // reset for reuse
                            String text;
                            int screenWidth = CatnutUtils.getScreenWidth(getActivity());
                            int max = getActivity().getResources().getDimensionPixelSize(R.dimen.max_thumb_width);
                            if (screenWidth > max) {
                                screenWidth = max;
                            }

                            LayoutInflater inflater = LayoutInflater.from(getActivity());
                            if (!TextUtils.isEmpty(_question)) {
                                ViewGroup questionHolder = (ViewGroup) view.findViewById(R.id.question);
                                for (int i = 0; i < questionSegment.size(); i++) {
                                    text = questionSegment.get(i);
                                    if (!TextUtils.isEmpty(text)) {
                                        if ((i & 1) == 0) {
                                            TextView section = (TextView) inflater.inflate(R.layout.zhihu_text,
                                                    null);
                                            section.setTextSize(16);
                                            section.setTextColor(
                                                    getResources().getColor(R.color.black50PercentColor));
                                            section.setText(Html.fromHtml(text));
                                            section.setMovementMethod(LinkMovementMethod.getInstance());
                                            CatnutUtils.removeLinkUnderline(section);
                                            questionHolder.addView(section);
                                        } else {
                                            ImageView imageView = getImageView();
                                            Uri uri = useCachedImg
                                                    ? Zhihu.getCacheImageLocation(getActivity(), Uri.parse(text))
                                                    : Uri.parse(text);
                                            Picasso.with(getActivity()).load(uri).centerCrop()
                                                    .resize(screenWidth,
                                                            (int) (Constants.GOLDEN_RATIO * screenWidth))
                                                    .error(R.drawable.error).into(imageView);
                                            imageView.setTag(l++); // for click
                                            imageView.setOnClickListener(ZhihuItemFragment.this);
                                            mImageUrls.add(uri);
                                            questionHolder.addView(imageView);
                                        }
                                    }
                                }
                            }

                            Typeface typeface = CatnutUtils.getTypeface(CatnutApp.getTingtingApp().getPreferences(),
                                    getString(R.string.pref_customize_tweet_font),
                                    getString(R.string.default_typeface));
                            ViewGroup answerHolder = (ViewGroup) view.findViewById(R.id.answer);
                            for (int i = 0; i < contentSegment.size(); i++) {
                                text = contentSegment.get(i);
                                if (!TextUtils.isEmpty(text)) {
                                    if ((i & 1) == 0) {
                                        TextView section = (TextView) inflater.inflate(R.layout.zhihu_text, null);
                                        section.setText(Html.fromHtml(text));
                                        CatnutUtils.setTypeface(section, typeface);
                                        CatnutUtils.removeLinkUnderline(section);
                                        section.setMovementMethod(LinkMovementMethod.getInstance());
                                        answerHolder.addView(section);
                                    } else {
                                        ImageView image = getImageView();
                                        Uri uri = useCachedImg
                                                ? Zhihu.getCacheImageLocation(getActivity(), Uri.parse(text))
                                                : Uri.parse(text);
                                        Picasso.with(getActivity()).load(uri).centerCrop()
                                                .resize(screenWidth, (int) (Constants.GOLDEN_RATIO * screenWidth))
                                                .error(R.drawable.error).into(image);
                                        image.setTag(l++); // 
                                        image.setOnClickListener(ZhihuItemFragment.this);
                                        mImageUrls.add(uri);
                                        answerHolder.addView(image);
                                    }
                                }
                            }
                            author.setText(_nick);
                            lastAlterDate.setText(DateUtils.getRelativeTimeSpanString(_lastAlterDate));
                            if (mSwipeRefreshLayout != null) {
                                mSwipeRefreshLayout.setRefreshing(false);
                            }
                        }
                    });
                } else {
                    cursor.close();
                }
            }
        })).start();
    }

    private ImageView getImageView() {
        ImageView image = new ImageView(getActivity());
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        lp.setMargins(0, 10, 0, 10);
        image.setLayoutParams(lp);
        image.setAdjustViewBounds(true);
        image.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return CatnutUtils.imageOverlay(v, event);
            }
        });
        image.setOnClickListener(this);
        return image;
    }

    private void processText(String _content, Matcher matcher, List<String> contentSegment) {
        int start;
        int lastStart = 0;
        while (matcher.find()) {
            start = matcher.start();
            contentSegment.add(_content.substring(lastStart, start));
            lastStart = matcher.end();
            contentSegment.add(matcher.group(1));
        }
        // no image, fallback
        if (contentSegment.size() == 0) {
            contentSegment.add(_content);
        } else {
            // append tail
            if ((contentSegment.size() - 1 & 1) == 0) {
                contentSegment.add(null); // place holder...
            }
            contentSegment.add(_content.substring(lastStart));
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        getActivity().getActionBar().setTitle(getString(R.string.read_zhihu));
        // 
        new Thread(new MarkHasReadRunable(mAnswerId, getActivity(), true)).start();
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        menu.add(Menu.NONE, ACTION_VIEW_ALL_ON_WEB, Menu.NONE, getString(R.string.view_all_answer));
        menu.add(Menu.NONE, ACTION_VIEW_ON_WEB, Menu.NONE, getString(R.string.zhihu_view_on_web));
        super.onCreateContextMenu(menu, v, menuInfo);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        viewOutside(item.getItemId());
        return super.onContextItemSelected(item);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.add(Menu.NONE, ACTION_VIEW_ALL_ON_WEB, Menu.NONE, getString(R.string.view_all_answer))
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
        menu.add(Menu.NONE, ACTION_VIEW_ON_WEB, Menu.NONE, getString(R.string.zhihu_view_on_web))
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        viewOutside(item.getItemId());
        return super.onOptionsItemSelected(item);
    }

    private void viewOutside(int which) {
        switch (which) {
        case ACTION_VIEW_ON_WEB:
            startActivity(new Intent(Intent.ACTION_VIEW,
                    Uri.parse("http://www.zhihu.com/question/" + mQuestionId + "/answer/" + mAnswerId)));
            break;
        case ACTION_VIEW_ALL_ON_WEB:
            startActivity(
                    new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.zhihu.com/question/" + mQuestionId)));
            break;
        default:
            break;
        }
    }

    @Override
    public void onRefresh() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                // just for fun~
                try {
                    TimeUnit.MILLISECONDS.sleep(1500);
                } catch (InterruptedException e) {
                }
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mSwipeRefreshLayout != null) {
                            mSwipeRefreshLayout.setRefreshing(false);
                        }
                    }
                });
            }
        }).start();
    }

    @Override
    public void onClick(View v) {
        ImageView image = (ImageView) v;
        ((ImageView) v).getDrawable().clearColorFilter();
        image.invalidate();
        Integer index = (Integer) v.getTag();
        Intent intent = SingleFragmentActivity.getIntent(getActivity(), SingleFragmentActivity.GALLERY);
        intent.putExtra(GalleryPagerFragment.CUR_INDEX, index);
        intent.putExtra(GalleryPagerFragment.URLS, mImageUrls);
        intent.putExtra(GalleryPagerFragment.TITLE, getString(R.string.view_photos));
        startActivity(intent);
    }

    /**
     * 
     */
    public static class MarkHasReadRunable implements Runnable {

        private long answerId;
        private Context context;
        private boolean hasRead;

        public MarkHasReadRunable(long answerId, Context context, boolean hasRead) {
            this.answerId = answerId;
            this.context = context;
            this.hasRead = hasRead;
        }

        @Override
        public void run() {
            ContentValues values = new ContentValues();
            values.put(Zhihu.HAS_READ, hasRead);
            context.getContentResolver().update(CatnutProvider.parse(Zhihu.MULTIPLE, answerId), values, null, null);
        }
    }
}