編輯:關於Android編程
package com.jiketuandui.antinetfraud.View; import android.animation.ValueAnimator; import android.content.Context; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import com.jiketuandui.antinetfraud.Adapter.MyWrapAdapter; import com.jiketuandui.antinetfraud.R; import java.util.ArrayList; /** * Created by Notzuonotdied on 2016/9/3. * 自定義RecycleView實現下拉刷新和上拉刷新 */ public class MyRecycleView extends RecyclerView { /** * 正在刷新 */ public final static int STATE_REFRESHING = 2; /** * 下拉刷新 */ private final static int STATE_NORMAL = 0; /** * 松開刷新 */ private final static int STATE_READY = 1; /** * 判斷用戶是否觸摸屏幕 */ boolean isOnTouching; /** * 判斷是否需要進行刷新 */ boolean isRefresh; /** * 判斷是否需要加載更多 */ boolean isLoadMore; /** * 拖動後X的最後位置 */ int lastX; /** * 拖動後Y的最後位置 */ int lastY; /** * 定義頭部的View */ View headerView; /** * 定義尾部的View */ View footerView; /** * 頭部的View的高度 */ int headerViewHeight; /** * 設置響應事件 */ private MyRecycleViewListener myRecycleViewListener; /** * 默認的狀態 */ private int mState = STATE_NORMAL; /** * 顯示文本信息的TextView */ private TextView status; /** * 用於顯示頭部和尾部item的adapter */ MyWrapAdapter myWrapAdapter; private String[] textViewString = {"松開刷新...", "下拉刷新...", "正在刷新..."}; /** * Instantiates a new My recycle view. * * @param context the context */ public MyRecycleView(Context context) { super(context); } /** * Instantiates a new My recycle view. * * @param context the context * @param attrs the attrs */ public MyRecycleView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } /** * Instantiates a new My recycle view. * * @param context the context * @param attrs the attrs * @param defStyle the def style */ public MyRecycleView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * On status change. * * @param status the status */ public void onStatusChange(int status) { mState = status; switch (status) { case STATE_READY: this.status.setText(textViewString[STATE_READY]); break; case STATE_NORMAL: this.status.setText(textViewString[STATE_NORMAL]); break; case STATE_REFRESHING: this.status.setText(textViewString[STATE_REFRESHING]); if (myRecycleViewListener != null) { myRecycleViewListener.onRefresh(); } break; } } /** * Gets my recycle view listener. * * @return the my recycle view listener */ public MyRecycleViewListener getMyRecycleViewListener() { return myRecycleViewListener; } /** * Sets my recycle view listener. * * @param myRecycleViewListener the my recycle view listener */ public void setMyRecycleViewListener(MyRecycleViewListener myRecycleViewListener) { this.myRecycleViewListener = myRecycleViewListener; } @Override public boolean onTouchEvent(MotionEvent e) { int x = (int) e.getX(); int y = (int) e.getY(); switch (e.getAction()) { case MotionEvent.ACTION_DOWN: isOnTouching = true; break; case MotionEvent.ACTION_MOVE: // 判斷是否滑動到了頭部 if (!canScrollVertically(-1)) { if (Math.abs(lastY - y) > Math.abs(lastX - x)) { isRefresh = true; changeHeight(lastY - y); } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: isRefresh = false; isOnTouching = false; if (mState == STATE_READY) { onStatusChange(STATE_REFRESHING); } autoSize(); break; } lastX = x; lastY = y; return super.onTouchEvent(e); } /** * 下拉刷新拖動的屬性動畫效果 * */ private void autoSize() { // 當前的高度 int currentHeight = headerView.getHeight(); // View拖動後所在的高度 int targetHeight = headerViewHeight; if (mState == STATE_READY || mState == STATE_REFRESHING) { targetHeight = headerViewHeight * 2; } if (mState == STATE_REFRESHING) { if (currentHeight < headerViewHeight * 2) { return; } } // 屬性動畫 ValueAnimator valueAnimator = ValueAnimator.ofInt(currentHeight, targetHeight); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { int animateValue = (int) valueAnimator.getAnimatedValue(); setStateByHeight(animateValue, true); headerView.getLayoutParams().height = animateValue; headerView.requestLayout(); } }); valueAnimator.start(); } @Override public void setLayoutManager(LayoutManager layout) { super.setLayoutManager(layout); this.addOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (isRefresh) { return; } if (mState != STATE_NORMAL) { return; } // 判斷是否是最後一個item LayoutManager layoutManager = getLayoutManager(); // 可見的item數目 int visibleChildCount = layoutManager.getChildCount(); if (visibleChildCount > 0 && newState == RecyclerView.SCROLL_STATE_IDLE && !isLoadMore) { View lastVisibleView = recyclerView.getChildAt(recyclerView.getChildCount() - 1); int lastVisiblePosition = recyclerView.getChildLayoutPosition(lastVisibleView); if (lastVisiblePosition >= layoutManager.getItemCount() - 1) { footerView.setVisibility(VISIBLE); isLoadMore = true; if (myRecycleViewListener != null) { myRecycleViewListener.onLoadMore(); } else { footerView.setVisibility(GONE); } } } } }); } /** * 回拉效果 * */ private void changeHeight(int changeHeight) { headerView.getLayoutParams().height -= changeHeight; headerView.requestLayout(); setStateByHeight(headerView.getHeight(), false); } /** * 根據拖動的高度進行判斷做出相應的響應 * */ private void setStateByHeight(int height, boolean isAuto) { if (mState == STATE_REFRESHING) { return; } if (height - headerViewHeight < headerViewHeight) { onStatusChange(STATE_NORMAL); } else if (height - headerViewHeight > headerViewHeight) { onStatusChange(STATE_READY); } else if (height - headerViewHeight == headerViewHeight && !isOnTouching && !isAuto) { onStatusChange(STATE_REFRESHING); } } @Override public void setAdapter(Adapter adapter) { ArrayListheaders = new ArrayList<>(); ArrayList footers = new ArrayList<>(); /** * 頭部 * */ View refreshView = LayoutInflater.from(getContext()).inflate(R.layout.my_refresh, null); headerView = refreshView; RelativeLayout headerLayout = new RelativeLayout(getContext()); headerLayout.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); headerLayout.addView(headerView, RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); headerLayout.setGravity(Gravity.BOTTOM); status = (TextView) refreshView.findViewById(R.id.status); // 內部更新UI headerView.post(new Runnable() { @Override public void run() { headerViewHeight = headerView.getHeight(); RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) headerView.getLayoutParams(); lp.setMargins(0, -headerViewHeight, 0, 0); headerView.requestLayout(); } }); headers.add(headerLayout); /** * 尾部 * */ LinearLayout footerLayout = new LinearLayout(getContext()); footerLayout.setGravity(Gravity.CENTER); footerLayout.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); footers.add(footerLayout); footerLayout.setPadding(0, 15, 0, 15); footerLayout.addView(new ProgressBar(getContext(), null, android.R.attr.progressBarStyleSmall)); TextView text = new TextView(getContext()); text.setText("正在加載..."); footerLayout.addView(text); footerView = footerLayout; footerView.setVisibility(GONE); myWrapAdapter = new MyWrapAdapter(adapter, headers, footers); super.setAdapter(myWrapAdapter); } /** * Sets load more complete. */ public void setLoadMoreComplete() { footerView.setVisibility(GONE); isLoadMore = false; } /** * Sets refresh complete. */ public void setRefreshComplete() { onStatusChange(STATE_NORMAL); autoSize(); } /** * 對外接口 */ public interface MyRecycleViewListener { /** * On refresh. */ void onRefresh(); /** * On load more. */ void onLoadMore(); } }
package com.jiketuandui.antinetfraud.Adapter; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; /** * 實現顯示頭部和尾部item的adapter,把頭部尾部的事情交給這個adapter來做,其他的交給子adapter */ public class MyWrapAdapter extends RecyclerView.Adapter{ public ArrayList headerViews = new ArrayList<>(); public ArrayList footViews = new ArrayList<>(); public RecyclerView.Adapter adapter; public MyWrapAdapter(RecyclerView.Adapter adapter, ArrayList headerViews, ArrayList footViews) { this.adapter = adapter; this.headerViews = headerViews; this.footViews = footViews; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == RecyclerView.INVALID_TYPE) { //頭部item return new RecyclerView.ViewHolder(headerViews.get(0)) { }; } else if (viewType == (RecyclerView.INVALID_TYPE - 1)) { //尾部item return new RecyclerView.ViewHolder(footViews.get(0)) { }; } return adapter.onCreateViewHolder(parent, viewType); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (position >= 0 && position < headerViews.size()) { return; } if (adapter != null) { int p = position - headerViews.size(); if (p < adapter.getItemCount()) { adapter.onBindViewHolder(holder, p); } } } @Override public int getItemViewType(int position) { if (position >= 0 && position < headerViews.size()) { //如果是頭部則返回一個不可用的標識,表示這是頭部item return RecyclerView.INVALID_TYPE; } if (adapter != null) { int p = position - headerViews.size(); if (p < adapter.getItemCount()) { return adapter.getItemViewType(p); } } return RecyclerView.INVALID_TYPE - 1;//默認返回表示是尾部的item } @Override public int getItemCount() { return getCount(); } public int getCount() { int count = headerViews.size() + footViews.size(); if (adapter != null) { count += adapter.getItemCount(); } return count; } }
package com.jiketuandui.antinetfraud.Adapter; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.support.v7.widget.RecyclerView; import android.view.View; /** * Created by baoyunlong * 這個是用來更改Item的顯示效果的,修改onDraw即可 */ public class MyItemDecoration extends RecyclerView.ItemDecoration { private int size = 2; @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.parseColor("#eeeeee")); paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(2); int startY = child.getTop() - size; int startX = child.getLeft(); int endY = child.getTop() - size; int enx = child.getRight(); c.drawLine(startX, startY, enx, endY, paint); } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.set(0, size, 0, 0); } }
微信網頁版怎麼看以前的聊天記錄?上班族寶寶們幾乎都會在網頁上進行微信聊天,微信網頁版比手機要方便得多,下文介紹微信網頁版查看聊天記錄方法,一起來和小編了解下
如下圖。在Android上實現起來就不太容易,有些效果還是不如web端酷炫。)我們的Demo,Ac娘鎮樓(圖很渣,也忽略底下的SeekBar,這不是重點)一些動畫,效果錄
一、加載過程動態展示動畫在APP的研發中,加載過程用動畫更改時間的消耗,增強用戶體驗。而有個更精細的加載過程動畫,會不斷從細節優化APP的體驗。且隨著APP與服務器交互的
本文會實現一個類似網易新聞(不說網易新聞大家可能不知道大概是什麼樣子)點擊超多選項卡,選項卡動態滑動的效果。首先來看看布局,就是用HorizontalScro