package com.maxiee.heartbeat.ui;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.maxiee.heartbeat.R;
import com.maxiee.heartbeat.common.FileUtils;
import com.maxiee.heartbeat.common.GalleryUtils;
import com.maxiee.heartbeat.common.TimeUtils;
import com.maxiee.heartbeat.common.tagview.Tag;
import com.maxiee.heartbeat.common.tagview.TagView;
import com.maxiee.heartbeat.database.utils.EventUtils;
import com.maxiee.heartbeat.database.utils.ImageUtils;
import com.maxiee.heartbeat.database.utils.LabelUtils;
import com.maxiee.heartbeat.database.utils.ThoughtUtils;
import com.maxiee.heartbeat.model.Event;
import com.maxiee.heartbeat.model.Image;
import com.maxiee.heartbeat.model.Label;
import com.maxiee.heartbeat.model.Thoughts;
import com.maxiee.heartbeat.ui.adapter.ThoughtTimeaxisAdapter;
import com.maxiee.heartbeat.ui.common.BaseActivity;
import java.util.ArrayList;
import butterknife.Bind;
import butterknife.ButterKnife;
/**
* Created by maxiee on 15-6-13.
*/
public class EventDetailActivity extends BaseActivity {
private final static String TAG = EventDetailActivity.class.getSimpleName();
public static final String EXTRA_NAME = "id";
private static final int ADD_IMAGE = 1127;
private static final int LONG_IMAGE_IMAGE_MAX_HEIGHT = 300;
private long mId;
private Event mEvent;
@Bind(R.id.tv_event) TextView mTvEvent;
@Bind(R.id.recyclerview) RecyclerView mRecyclerView;
@Bind(R.id.tagview) TagView mTagView;
@Bind(R.id.tv_time) TextView mTvTime;
@Bind(R.id.backdrop) ImageView mImageBackDrop;
@Bind(R.id.card_event) View mCardEvent;
@Bind(R.id.add_imgae) TextView mAddImageText;
@Bind(R.id.header) View mHeaderView;
private LinearLayoutManager mLayoutManager;
private ThoughtTimeaxisAdapter mAdapter;
private Image mImage;
private Thoughts mThoughts;
private String mSortingType;
private boolean mHasImage = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_detail);
ButterKnife.bind(this);
Intent intent = getIntent();
mId = intent.getLongExtra(EXTRA_NAME, -1);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
mSortingType = sp.getString("time_axis_sorting", "0");
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setTitle("");
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mEvent = EventUtils.getEvent(this, mId);
mTagView.setOnTagClickListener(new TagView.OnTagClickListener() {
@Override
public void onTagClick(Tag tag, int position) {
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.setClass(EventDetailActivity.this, LabelDetailActivity.class);
i.putExtra("tag_text", tag.text);
startActivity(i);
}
});
mTvTime.setText(TimeUtils.parseTime(this, mEvent.getTimestamp()));
mCardEvent.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Intent i = new Intent(EventDetailActivity.this, AddEventActivity.class);
i.putExtra(AddEventActivity.ID_EVENT_MODIFY, mId);
startActivity(i);
return true;
}
});
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(EventDetailActivity.this, AddEditThoughtActivity.class);
i.putExtra(AddEditThoughtActivity.MODE, AddEditThoughtActivity.MODE_NEW);
i.putExtra(AddEditThoughtActivity.EVENT_KEY, mId);
startActivity(i);
}
});
mThoughts = ThoughtUtils.getThoughtsByEventId(this, mId);
mAdapter = new ThoughtTimeaxisAdapter(mThoughts);
mRecyclerView.setAdapter(mAdapter);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.transparent));
}
}
@Override
protected void onResume() {
super.onResume();
mEvent = EventUtils.getEvent(this, mId);
mTvEvent.setText(mEvent.getEvent());
mTvTime.setText(TimeUtils.parseTime(this, mEvent.getTimestamp()));
mThoughts = ThoughtUtils.getThoughtsByEventId(this, mEvent.getId());
mAdapter.setData(mThoughts);
mAdapter.notifyDataSetChanged();
initImage();
updateTagView();
}
private void initImage() {
mImage = ImageUtils.getImageByEventId(this, mEvent.getId());
if (mImage == null) {
mAddImageText.setVisibility(View.VISIBLE);
mAddImageText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GalleryUtils.openGallery(EventDetailActivity.this);
}
});
} else {
changeHeaderToImage();
mAddImageText.setVisibility(View.INVISIBLE);
Glide.with(this)
.load(GalleryUtils.getImagePath(mImage.getPath()))
.into(mImageBackDrop);
mImageBackDrop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(EventDetailActivity.this, GalleryActivity.class);
i.putExtra(GalleryActivity.EVENT_ID, mEvent.getId());
startActivity(i);
}
});
}
}
private void changeHeaderToImage() {
mHeaderView.setVisibility(View.GONE);
mImageBackDrop.setVisibility(View.VISIBLE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_event_detail, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
this.onBackPressed();
return true;
}
if (id == R.id.long_iamge) {
// generateLongImage();
new LongImageTask().execute();
}
return super.onOptionsItemSelected(item);
}
public void updateTagView() {
mTagView.clear();
ArrayList<Label> labels = LabelUtils.getLabelsByEvent(this, mEvent);
for (Label l : labels) mTagView.addTag(new Tag(l.getLabel()));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String path = GalleryUtils.onActivityResult(this, requestCode, resultCode, data);
if (path != null) ImageUtils.addImage(this, mEvent.getId(), path);
initImage();
}
private class LongImageTask extends AsyncTask<Void, Integer, Void> {
private ProgressDialog progressDialog;
private Canvas mBitmapHolder;
private int mWidth;
private Bitmap mBitmap;
private View mView;
private TextView mTv;
private ImageView mIv;
private TextView mTvOrder;
private TextView mTvTime;
private View mPoint;
private LinearLayout mLL;
private int mYPos = 0;
private int mHeight = 0;
@Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(EventDetailActivity.this);
progressDialog.setMessage(getString(R.string.generating));
progressDialog.setCancelable(false);
progressDialog.show();
// mCardEvent.setBackgroundColor(ContextCompat.getColor(EventDetailActivity.this, android.support.v7.cardview.R.color.cardview_light_background));
// create a parent layout of time-axis item
FrameLayout mFl = new FrameLayout(EventDetailActivity.this);
mFl.setBackgroundColor(ContextCompat.getColor(EventDetailActivity.this, R.color.window_background));
// get display width
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
mWidth = displaymetrics.widthPixels;
// create time-axis item view from layout
mView = getLayoutInflater().inflate(R.layout.item_thought_timeaxis, mFl);
mTv = (TextView) mView.findViewById(R.id.tv_thought);
mIv = (ImageView) mView.findViewById(R.id.image_thought);
mTvOrder = (TextView) mView.findViewById(R.id.tv_order);
mTvTime = (TextView) mView.findViewById(R.id.tv_time);
mPoint = mView.findViewById(R.id.time_point);
setPointColor();
createBottomLogoLayout();
}
private void setPointColor() {
final TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true);
int color = typedValue.data;
Drawable d = ContextCompat.getDrawable(EventDetailActivity.this, R.drawable.circle_timeaxis);
d.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
mPoint.setBackgroundDrawable(d);
}
private void createBottomLogoLayout() {
mLL = new LinearLayout(EventDetailActivity.this);
mLL.setBackgroundColor(ContextCompat.getColor(EventDetailActivity.this, R.color.window_background));
ViewGroup.LayoutParams LLParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 100);
mLL.setLayoutParams(LLParams);
mLL.setOrientation(LinearLayout.HORIZONTAL);
mLL.setPadding(24, 0, 0, 0);
mLL.setGravity(Gravity.CENTER_VERTICAL);
ImageView icon = new ImageView(EventDetailActivity.this);
icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
icon.setImageDrawable(ContextCompat.getDrawable(EventDetailActivity.this, R.mipmap.ic_launcher));
mLL.addView(icon);
TextView hb = new TextView(EventDetailActivity.this);
hb.setText("@心动小分队");
mLL.addView(hb);
mLL.measure(View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
mHeight += mLL.getMeasuredHeight();
}
@Override
protected Void doInBackground(Void... params) {
mHeight += measureViewsHeight(mWidth);
Log.d("maxiee", "生成Bitmap:" + String.valueOf(mWidth) + "," + String.valueOf(mHeight));
mBitmap = Bitmap.createBitmap(
mWidth,
mHeight,
Bitmap.Config.RGB_565);
mBitmapHolder = new Canvas(mBitmap);
if (mImage != null) publishProgress(-2);//backdrop
publishProgress(-1);//event card
for (int i=0; i<mThoughts.length(); i++) {
publishProgress(i);
}
publishProgress(-3);
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
int progress = values[0];
if (progress == -2) {
// draw backdrop
if (mImage != null) {
int backDropHeight = mImageBackDrop.getMeasuredHeight();
mImageBackDrop.layout(0, 0, mWidth, backDropHeight);
mImageBackDrop.buildDrawingCache();
Bitmap backDropBitmap = mImageBackDrop.getDrawingCache();
if (backDropBitmap != null) {
mBitmapHolder.drawBitmap(backDropBitmap, 0, 0, null);
}
mYPos += backDropHeight;
}
}
else if (progress == -1) {
// draw cardview
int cardEventHeight = mCardEvent.getMeasuredHeight();
mCardEvent.layout(0, 0, mWidth, cardEventHeight);
mCardEvent.buildDrawingCache();
Bitmap eventBitmap = mCardEvent.getDrawingCache();
if (eventBitmap != null) {
mBitmapHolder.drawBitmap(eventBitmap, 0, mYPos, null);
}
mYPos += cardEventHeight;
} else if (progress == -3) {
mLL.layout(0, 0, mWidth, mLL.getMeasuredHeight());
Log.d("maxiee", "llMeasureH:" + String.valueOf(mLL.getMeasuredHeight()));
mLL.buildDrawingCache();
Bitmap b = mLL.getDrawingCache();
if (b != null) {
Log.d("maxiee", "Logo不为空");
mBitmapHolder.drawBitmap(b, 0, mYPos, null);
}
} else if (progress >= 0) {
// draw item
Bitmap itemBitmap;
int childHeight;
mTv.setText(mThoughts.get(progress).getThought());
mTvOrder.setText(getOrder(progress, mThoughts.length()));
long time = mThoughts.get(progress).getTimeStamp();
mTvTime.setText(TimeUtils.parseTime(EventDetailActivity.this, time));
if (mThoughts.get(progress).hasImage()) {
mIv.setVisibility(View.VISIBLE);
Bitmap bmp = loadBitmap(mTv.getMeasuredWidth(), LONG_IMAGE_IMAGE_MAX_HEIGHT, mThoughts.get(progress).getPath());
mIv.setImageBitmap(bmp);
} else {
mIv.setVisibility(View.GONE);
}
mView.measure(View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
childHeight = mView.getMeasuredHeight();
mView.layout(0, 0, mWidth, childHeight);
mView.buildDrawingCache();
itemBitmap = mView.getDrawingCache();
if (itemBitmap != null) {
mBitmapHolder.drawBitmap(itemBitmap, 0, mYPos, null);
}
mView.destroyDrawingCache();
mYPos += childHeight;
}
}
@Override
protected void onPostExecute(Void aVoid) {
// drawViews(mView, mBitmapHolder, mWidth);
String s = FileUtils.saveLongImage(EventDetailActivity.this, mBitmap);
progressDialog.cancel();
if (!s.isEmpty()) {
try {
Log.d("maxiee", "地址:" + s);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + s)));
} catch (Exception e) {e.printStackTrace();}
AlertDialog.Builder builder = new AlertDialog.Builder(
EventDetailActivity.this,
R.style.AppTheme_Dialog);
builder.setTitle(getString(R.string.long_image));
builder.setMessage(getString(R.string.generate_ok) + s);
builder.setCancelable(false);
final String path = s;
builder.setPositiveButton(R.string.view, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + path), "image/*");
startActivity(intent);
dialog.cancel();
}
});
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else {
Toast.makeText(EventDetailActivity.this, getString(R.string.add_failed), Toast.LENGTH_LONG).show();
}
}
private int measureViewsHeight(int width) {
int height = 0;
if (mImage != null) height += mImageBackDrop.getMeasuredHeight();
height += mCardEvent.getMeasuredHeight();
mView.measure(View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
int screenWidth = mTv.getMeasuredWidth();
mIv.setVisibility(View.GONE);
// get Size
int rvItemNum = mThoughts.length();
for (int i=0; i<rvItemNum; i++) {
mTv.setText(mThoughts.get(i).getThought());
if (mThoughts.get(i).hasImage()) {
mIv.setVisibility(View.VISIBLE);
Bitmap bmp = loadBitmap(screenWidth, LONG_IMAGE_IMAGE_MAX_HEIGHT, mThoughts.get(i).getPath());
mIv.setImageBitmap(bmp);
} else {
mIv.setVisibility(View.GONE);
}
mView.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
height += mView.getMeasuredHeight();
}
return height;
}
private Bitmap loadBitmap(int reqWidth, int reqHeight, String path) {
path = GalleryUtils.getImagePath(path);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
int imageWidth = options.outWidth;
int imageHeight = options.outHeight;
int inSampleSize = 1;
if (imageWidth > reqWidth) {
final int halfHeight = imageHeight / 2;
final int halfWidth = imageWidth / 2;
while ((halfHeight / inSampleSize) > reqHeight) {
inSampleSize *= 2;
}
}
options.inJustDecodeBounds = false;
options.inSampleSize = inSampleSize;
Bitmap b = BitmapFactory.decodeFile(path, options);
int orientation = 1;
try {
ExifInterface exif = new ExifInterface(path);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
} catch (Exception e) {e.printStackTrace();}
Matrix matrix = new Matrix();
switch (orientation) {
case 2:
matrix.setScale(-1, 1);
break;
case 3:
matrix.setRotate(180);
break;
case 4:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case 5:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case 6:
matrix.setRotate(90);
break;
case 7:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case 8:
matrix.setRotate(-90);
break;
default:
return b;
}
try {
Bitmap oriented = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
b.recycle();
return oriented;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return b;
}
}
}
private String getOrder(int position, int length) {
String order;
if (mSortingType.equals("0")) {
switch (position) {
case 0:
order = getString(R.string.firtime);
break;
case 1:
order = getString(R.string.sectime);
break;
default:
order = String.valueOf(position + 1) + ".";
break;
}
} else {
if (position == length - 1) {
order = getString(R.string.firtime);
} else if (position == length - 2) {
order = getString(R.string.sectime);
} else {
order = String.valueOf(length - position) + ".";
}
}
return order;
}
}