Created
January 7, 2015 22:48
-
-
Save XuNeal/bae5fbc99106558bfe62 to your computer and use it in GitHub Desktop.
Some code of Simple SNS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context="me.xuneal.simplesns.app.ui.CommentsActivity"> | |
<include layout="@layout/toolbar_image_logo" /> | |
<LinearLayout | |
android:id="@+id/ll_root_panel" | |
android:orientation="vertical" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_below="@+id/toolbar_actionbar" | |
android:background="@color/bg_comments" | |
> | |
<FrameLayout | |
android:layout_width="match_parent" | |
android:layout_height="0dp" | |
android:layout_weight="1"> | |
<android.support.v7.widget.RecyclerView | |
android:id="@+id/rv_comments" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:scrollbars="none" /> | |
<View | |
android:layout_width="match_parent" | |
android:layout_height="4dp" | |
android:layout_gravity="bottom" | |
android:background="@drawable/shadow_top" /> | |
</FrameLayout> | |
<LinearLayout | |
android:id="@+id/ll_send_panel" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:background="@color/bg_comments" | |
android:gravity="center_vertical" | |
android:paddingBottom="4dp" | |
android:paddingLeft="8dp" | |
android:paddingRight="8dp" | |
android:paddingTop="8dp"> | |
<EditText | |
android:id="@+id/tv_comment_content" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_weight="1" | |
android:textColor="#555555" | |
android:textSize="14sp" /> | |
<me.xuneal.simplesns.app.ui.components.SendCommentButton | |
android:id="@+id/scb_send" | |
android:layout_width="72dp" | |
android:layout_height="match_parent" | |
android:layout_marginBottom="2dp" | |
android:layout_marginLeft="8dp" | |
android:background="@drawable/btn_send_comment" | |
android:elevation="4dp" | |
android:orientation="vertical" | |
> | |
</me.xuneal.simplesns.app.ui.components.SendCommentButton> | |
</LinearLayout> | |
</LinearLayout> | |
</RelativeLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.xuneal.simplesns.app.ui; | |
import android.animation.Animator; | |
import android.animation.AnimatorListenerAdapter; | |
import android.os.Bundle; | |
import android.support.v4.view.ViewCompat; | |
import android.support.v7.widget.LinearLayoutManager; | |
import android.support.v7.widget.RecyclerView; | |
import android.text.TextUtils; | |
import android.view.Menu; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.view.ViewTreeObserver; | |
import android.view.animation.AccelerateInterpolator; | |
import android.view.animation.AnimationUtils; | |
import android.view.animation.DecelerateInterpolator; | |
import android.widget.EditText; | |
import android.widget.LinearLayout; | |
import com.avos.avoscloud.*; | |
import it.gmariotti.recyclerview.itemanimator.SlideInOutBottomItemAnimator; | |
import me.xuneal.simplesns.app.R; | |
import me.xuneal.simplesns.app.model.Account; | |
import me.xuneal.simplesns.app.model.Comment; | |
import me.xuneal.simplesns.app.model.Tweet; | |
import me.xuneal.simplesns.app.ui.components.SendCommentButton; | |
import me.xuneal.simplesns.app.util.AccountUtils; | |
import me.xuneal.simplesns.app.util.Utils; | |
import org.joda.time.LocalDateTime; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class CommentsActivity extends BaseActivity implements View.OnClickListener, SendCommentButton.OnSendClickListener { | |
public static final String ARG_DRAWING_START_LOCATION = "arg_drawing_start_location"; | |
public static final String ARG_POST_ID = "arg_post_id"; | |
private List<Comment> mComments = new ArrayList<>(); | |
private RecyclerView mRvComments; | |
private EditText mTvCommentContent; | |
private SendCommentButton mScbSend; | |
private CommentAdapter mCommentAdapter; | |
private int drawingStartLocation; | |
private LinearLayout mLlRootPanel; | |
private LinearLayout mLlSendPanel; | |
private Tweet mTweet; | |
/** | |
* Find the Views in the layout<br /> | |
* <br /> | |
* Auto-created on 2014-12-11 13:48:44 by Android Layout Finder | |
* (http://www.buzzingandroid.com/tools/android-layout-finder) | |
*/ | |
private void findViews() { | |
mLlRootPanel = (LinearLayout) findViewById(R.id.ll_root_panel); | |
mRvComments = (RecyclerView) findViewById(R.id.rv_comments); | |
mTvCommentContent = (EditText) findViewById(R.id.tv_comment_content); | |
mLlSendPanel = (LinearLayout) findViewById(R.id.ll_send_panel); | |
mScbSend = (SendCommentButton) findViewById(R.id.scb_send); | |
mScbSend.setOnSendClickListener(this); | |
} | |
/** | |
* Handle button click events<br /> | |
* <br /> | |
* Auto-created on 2014-12-11 13:48:44 by Android Layout Finder | |
* (http://www.buzzingandroid.com/tools/android-layout-finder) | |
*/ | |
@Override | |
public void onClick(View v) { | |
if (v == mScbSend) { | |
// Handle clicks for mScbSend | |
if (TextUtils.isEmpty(mTvCommentContent.getText().toString())) return; | |
Comment comment = new Comment(); | |
comment.setPoster(AVUser.getCurrentUser(Account.class)); | |
comment.setPostTime(LocalDateTime.now().toString("yyyy-MM-dd HH:mm")); | |
comment.setContent(mTvCommentContent.getText().toString()); | |
comment.setTweet(mTweet); | |
comment.saveInBackground(); | |
mCommentAdapter.addItem(comment); | |
} | |
} | |
@Override | |
public boolean onCreateOptionsMenu(Menu menu) { | |
getMenuInflater().inflate(R.menu.menu_main, menu); | |
MenuItem profileMenuItem = menu.findItem(R.id.action_profile); | |
profileMenuItem.setActionView(R.layout.menu_item_view); | |
return true; | |
} | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_comments); | |
findViews(); | |
getSupportActionBar().setDisplayShowHomeEnabled(true); | |
getSupportActionBar().setDisplayHomeAsUpEnabled(true); | |
mRvComments.setLayoutManager(new LinearLayoutManager(this)); | |
mRvComments.setHasFixedSize(true); | |
mCommentAdapter = new CommentAdapter(mComments); | |
mRvComments.setAdapter(mCommentAdapter); | |
mRvComments.setItemAnimator(new SlideInOutBottomItemAnimator(mRvComments)); | |
mRvComments.setOverScrollMode(View.OVER_SCROLL_NEVER); | |
mRvComments.setOnScrollListener(new RecyclerView.OnScrollListener() { | |
@Override | |
public void onScrollStateChanged(RecyclerView recyclerView, int newState) { | |
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { | |
mCommentAdapter.setAnimationsLocked(true); | |
} | |
} | |
}); | |
drawingStartLocation = getIntent().getIntExtra(ARG_DRAWING_START_LOCATION, 0); | |
mLlRootPanel.setVisibility(View.VISIBLE); | |
mLlRootPanel.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { | |
@Override | |
public boolean onPreDraw() { | |
mLlRootPanel.getViewTreeObserver().removeOnPreDrawListener(this); | |
startIntroAnimation(); | |
return true; | |
} | |
}); | |
} | |
private void startIntroAnimation() { | |
ViewCompat.setElevation(getActionBarToolbar(), 0); | |
mLlRootPanel.setScaleY(0.1f); | |
mLlRootPanel.setPivotY(drawingStartLocation); | |
mLlSendPanel.setTranslationY(100); | |
mLlRootPanel.animate() | |
.scaleY(1) | |
.setDuration(200) | |
.setInterpolator(new AccelerateInterpolator()) | |
.setListener(new AnimatorListenerAdapter() { | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
ViewCompat.setElevation(getActionBarToolbar(), Utils.dpToPx(8)); | |
animationContent(); | |
} | |
}) | |
.start(); | |
} | |
private void animationContent() { | |
mLlSendPanel.animate() | |
.translationY(0) | |
.setDuration(200) | |
.setInterpolator(new DecelerateInterpolator()) | |
.start(); | |
AVQuery<Tweet> tweetQuery = new AVQuery<>(Tweet.TABLE_NAME); | |
tweetQuery.getInBackground(getIntent().getStringExtra(ARG_POST_ID), new GetCallback<Tweet>() { | |
@Override | |
public void done(Tweet tweet, AVException e) { | |
mTweet = tweet; | |
AVQuery<Comment> query = new AVQuery<Comment>(Comment.TABLE_NAME); | |
query.whereEqualTo("tweet", tweet); | |
query.include("poster").findInBackground(new FindCallback<Comment>() { | |
@Override | |
public void done(List<Comment> list, AVException e) { | |
for (Comment comment : list) { | |
mComments.add(comment); | |
} | |
mCommentAdapter.updateItems(); | |
} | |
}); | |
} | |
}); | |
} | |
@Override | |
public void onBackPressed() { | |
ViewCompat.setElevation(getActionBarToolbar(), 0); | |
mLlRootPanel.animate() | |
.translationY(Utils.getScreenHeight(this)) | |
.setDuration(200) | |
.setListener(new AnimatorListenerAdapter() { | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
CommentsActivity.super.onBackPressed(); | |
overridePendingTransition(0, 0); | |
} | |
}) | |
.start(); | |
} | |
@Override | |
public void onSendClickListener(View v) { | |
if (validateComment()) { | |
Comment comment = new Comment(); | |
comment.setPoster(AccountUtils.getDefaultAccount()); | |
comment.setPostTime(LocalDateTime.now().toString("yyyy-MM-dd HH:mm")); | |
comment.setContent(mTvCommentContent.getText().toString()); | |
comment.setTweet(mTweet); | |
comment.saveInBackground(); | |
mCommentAdapter.addItem(comment); | |
if (mRvComments.getChildCount() > 1) | |
mRvComments.smoothScrollBy(0, mRvComments.getChildAt(0).getHeight() * mCommentAdapter.getItemCount()); | |
mTvCommentContent.setText(null); | |
mScbSend.setCurrentState(SendCommentButton.STATE_DONE); | |
} | |
} | |
private boolean validateComment() { | |
if (TextUtils.isEmpty(mTvCommentContent.getText())) { | |
mScbSend.startAnimation(AnimationUtils.loadAnimation(this, R.anim.shake_error)); | |
return false; | |
} | |
return true; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.xuneal.simplesns.app.ui.components; | |
import android.content.Context; | |
import android.graphics.*; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import com.larvalabs.svgandroid.SVG; | |
import com.larvalabs.svgandroid.SVGBuilder; | |
import me.xuneal.simplesns.app.R; | |
/** | |
* Created by xyz on 2014/12/30. | |
*/ | |
public class ProgressbarWithAnim extends View { | |
private Paint mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
private Paint mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
private float mCenterPointX; | |
private float mCenterPointY; | |
private float mRadius; | |
private Path mClipPath; | |
private Rect mCheckMarkRect; | |
private int mProgress = 0; | |
private RectF mArcRect; | |
private boolean finished; | |
private float mMove = 0.1f; | |
private float mTransitionY; | |
private Runnable mRunAfterSuccess; | |
public ProgressbarWithAnim(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
public ProgressbarWithAnim(Context context) { | |
super(context); | |
} | |
public void init() { | |
setLayerType(View.LAYER_TYPE_SOFTWARE, null); | |
mArcPaint.setStrokeWidth(10f); | |
mArcPaint.setColor(getResources().getColor(R.color.blue)); | |
mArcPaint.setStyle(Paint.Style.STROKE); | |
mCirclePaint.setStrokeWidth(3f); | |
mCirclePaint.setColor(getResources().getColor(R.color.lime)); | |
mCirclePaint.setStyle(Paint.Style.FILL); | |
mCenterPointX = getWidth() / 2; | |
mCenterPointY = getHeight() / 2; | |
mRadius = 100; | |
mClipPath = new Path(); | |
mClipPath.addCircle(mCenterPointX, mCenterPointY, 100, Path.Direction.CW); | |
mCheckMarkRect = new Rect((int) mCenterPointX - 90, (int) mCenterPointY + 90, (int) mCenterPointX + 90, (int) mCenterPointY + 270); | |
mArcRect = new RectF(mCenterPointX - 100f, mCenterPointY - 100f, mCenterPointX + 100f, mCenterPointY + 100f); | |
mTransitionY = (mRadius - 10) * 2; | |
postDelayed(mRunnable, 33); | |
} | |
Runnable mRunnable = new Runnable() { | |
@Override | |
public void run() { | |
if (!finished && mProgress >= 100) { | |
invalidate(); | |
postDelayed(mRunnable, 33); | |
} | |
} | |
}; | |
public void setProgress(int progress) { | |
mProgress = progress; | |
if (!finished && mProgress >= 100) { | |
postDelayed(mRunnable, 33); | |
} | |
invalidate(); | |
} | |
/** 设置上传完成的callBack */ | |
public void setCompletedListener(Runnable runAfterSuccess) { | |
mRunAfterSuccess = runAfterSuccess; | |
} | |
@Override | |
protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
super.onSizeChanged(w, h, oldw, oldh); | |
init(); | |
} | |
@Override | |
protected void onDraw(Canvas canvas) { | |
super.onDraw(canvas); | |
canvas.save(); | |
canvas.clipPath(mClipPath); | |
SVG svg = new SVGBuilder() | |
.readFromResource(getResources(), R.raw.svg_check_mark) | |
.build(); | |
if (mProgress >= 100) { | |
mTransitionY -= (mTransitionY * mMove); | |
canvas.drawCircle(mCenterPointX, mCenterPointY + mTransitionY, mRadius - 10, mCirclePaint); | |
Rect rect = new Rect(mCheckMarkRect.left, (int) (mCheckMarkRect.top - (180 * mMove)), | |
mCheckMarkRect.right, (int) (mCheckMarkRect.bottom - (180 * mMove))); | |
canvas.drawPicture(svg.getPicture(), rect); | |
mMove += 0.1; | |
if (mMove > 1) { | |
finished = true; | |
if (mRunAfterSuccess != null) | |
postDelayed(mRunAfterSuccess, 500); | |
} | |
} | |
canvas.drawArc(mArcRect, 0, 3.6f * mProgress, false, mArcPaint); | |
canvas.restore(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment