diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8d4dace2a8..520fb24c71 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -188,6 +188,9 @@ + diff --git a/app/src/main/assets/Home.html b/app/src/main/assets/Home.html index 16b49ea0f1..ffb1fa9257 100644 --- a/app/src/main/assets/Home.html +++ b/app/src/main/assets/Home.html @@ -57,7 +57,7 @@ article {

光环助手

-

乐于分享的人
是最帅(美)的^_^

+

乐于分享的人
是最帅的^_^

diff --git a/app/src/main/java/com/gh/common/constant/ItemViewType.java b/app/src/main/java/com/gh/common/constant/ItemViewType.java index 6d26516b38..19e3ef3699 100644 --- a/app/src/main/java/com/gh/common/constant/ItemViewType.java +++ b/app/src/main/java/com/gh/common/constant/ItemViewType.java @@ -22,5 +22,6 @@ public class ItemViewType { public static final int LOADING = 14; // 加载布局 public static final int LIBAO_NORMAL = 15; // 礼包正常布局 public static final int LIBAO_SKIP_CONCERN = 16; // 跳转关注管理页面布局 + public static final int KC_HINT = 16; } diff --git a/app/src/main/java/com/gh/common/util/DialogUtils.java b/app/src/main/java/com/gh/common/util/DialogUtils.java index bf1232b3ac..f3b5ae5917 100644 --- a/app/src/main/java/com/gh/common/util/DialogUtils.java +++ b/app/src/main/java/com/gh/common/util/DialogUtils.java @@ -169,6 +169,8 @@ public class DialogUtils { TextView hintdialog_confirm = (TextView) view.findViewById(R.id.hintdialog_confirm); + hintdialog_confirm.setText(confirm); + hintdialog_confirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/app/src/main/java/com/gh/common/util/ShareUtils.java b/app/src/main/java/com/gh/common/util/ShareUtils.java index 73d9eadd63..ed29c92211 100644 --- a/app/src/main/java/com/gh/common/util/ShareUtils.java +++ b/app/src/main/java/com/gh/common/util/ShareUtils.java @@ -126,11 +126,18 @@ public class ShareUtils { contentView.addView(shareRecyclerView,rlParams); if (!ispopupWindow) { - LinearLayout layout = (LinearLayout) view; + RelativeLayout layout = (RelativeLayout) view; layout.addView(contentView); - arrLabel[7] = "邮件"; - arrLogo[7] = R.drawable.share_email_logo; + arrLabel[6] = "邮件"; + arrLogo[6] = R.drawable.share_email_logo; + arrLabel[7] = "复制链接"; + arrLogo[7] = R.drawable.share_copyfont_logo; return; + } else { + arrLabel[6] = "复制链接"; + arrLogo[6] = R.drawable.share_copyfont_logo; + arrLabel[7] = "取消"; + arrLogo[7] = R.drawable.share_cancel_logo; } contentView.setBackgroundColor(0x8c000000); shareRecyclerView.setBackgroundColor(Color.WHITE); @@ -217,11 +224,8 @@ public class ShareUtils { shortMessageSahre(); break; case 6: - copyLink("推荐光环助手,绿色安全的手游加速助手:" + shareUrl); - break; - case 7: if (ispopupWindow) { - popupWindow.dismiss(); + copyLink(shareUrl); } else { Intent data=new Intent(Intent.ACTION_SENDTO); data.setData(Uri.parse("mailto:")); @@ -236,6 +240,13 @@ public class ShareUtils { context.startActivity(data); } break; + case 7: + if (ispopupWindow) { + popupWindow.dismiss(); + } else { + copyLink("推荐光环助手,绿色安全的手游加速助手:" + shareUrl); + } + break; } } }); @@ -482,10 +493,10 @@ public class ShareUtils { ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); cmb.setText(copyContent); if (ispopupWindow != null && ispopupWindow) { - popupWindow.dismiss(); - Utils.toast(context,"复制成功,请到微信/QQ粘贴分享"); - } else { Utils.toast(context,"复制成功"); + popupWindow.dismiss(); + } else { + Utils.toast(context,"复制成功,请到微信/QQ粘贴分享"); } } diff --git a/app/src/main/java/com/gh/common/util/UserIconUtils.java b/app/src/main/java/com/gh/common/util/UserIconUtils.java new file mode 100644 index 0000000000..4b627032fb --- /dev/null +++ b/app/src/main/java/com/gh/common/util/UserIconUtils.java @@ -0,0 +1,37 @@ +package com.gh.common.util; + +import com.gh.gamecenter.R; + +/** + * Created by khy on 2017/2/13. + * 获取用户默认头像工具类 + */ +public class UserIconUtils { + + /** + * @param i 默认图片位置(第几个) + * @return fresco 能解析的url + */ + public static String getUserIcon(int i){ + switch (i) { + case 1: + return "res:///" + R.drawable.user_default_icon1; + case 2: + return "res:///" + R.drawable.user_default_icon2; + case 3: + return "res:///" + R.drawable.user_default_icon3; + case 4: + return "res:///" + R.drawable.user_default_icon4; + case 5: + return "res:///" + R.drawable.user_default_icon5; + case 6: + return "res:///" + R.drawable.user_default_icon6; + case 7: + return "res:///" + R.drawable.user_default_icon7; + case 8: + return "res:///" + R.drawable.user_default_icon8; + default: + return "res:///" + R.drawable.user_default_icon1; + } + } +} diff --git a/app/src/main/java/com/gh/common/view/SwipeLayout.java b/app/src/main/java/com/gh/common/view/SwipeLayout.java new file mode 100644 index 0000000000..0fbb5d9a24 --- /dev/null +++ b/app/src/main/java/com/gh/common/view/SwipeLayout.java @@ -0,0 +1,1671 @@ +package com.gh.common.view; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Rect; +import android.support.annotation.Nullable; +import android.support.v4.view.GravityCompat; +import android.support.v4.view.ViewCompat; +import android.support.v4.widget.ViewDragHelper; +import android.util.AttributeSet; +import android.view.GestureDetector; +import android.view.Gravity; +import android.view.HapticFeedbackConstants; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.widget.AbsListView; +import android.widget.AdapterView; +import android.widget.FrameLayout; + +import com.gh.common.util.Utils; +import com.gh.gamecenter.R; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * 滑动的layout + */ +public class SwipeLayout extends FrameLayout { + @Deprecated + public static final int EMPTY_LAYOUT = -1; + private static final int DRAG_LEFT = 1; + private static final int DRAG_RIGHT = 2; + private static final int DRAG_TOP = 4; + private static final int DRAG_BOTTOM = 8; + private static final DragEdge DefaultDragEdge = DragEdge.Left; + + private int mTouchSlop; + + private DragEdge mCurrentDragEdge = DefaultDragEdge; + private ViewDragHelper mDragHelper; + + private int mDragDistance = 0; + private LinkedHashMap mDragEdges = new LinkedHashMap<>(); + private ShowMode mShowMode; + + private float[] mEdgeSwipesOffset = new float[4]; + + private List mSwipeListeners = new ArrayList<>(); + private List mSwipeDeniers = new ArrayList<>(); + private Map> mRevealListeners = new HashMap<>(); + private Map mShowEntirely = new HashMap<>(); + private Map mViewBoundCache = new HashMap<>();//save all children's bound, restore in onLayout + + private DoubleClickListener mDoubleClickListener; + + private boolean mSwipeEnabled = true; + private boolean[] mSwipesEnabled = new boolean[]{true, true, true, true}; + private boolean mClickToClose = false; + private float mWillOpenPercentAfterOpen=0.50f; + private float mWillOpenPercentAfterClose=0.50f; + + public enum DragEdge { + Left, + Top, + Right, + Bottom + } + + public enum ShowMode { + LayDown, + PullOut + } + + public SwipeLayout(Context context) { + this(context, null); + } + + public SwipeLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SwipeLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mDragHelper = ViewDragHelper.create(this, mDragHelperCallback); + mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SwipeLayout); + int dragEdgeChoices = a.getInt(R.styleable.SwipeLayout_drag_edge, DRAG_LEFT); + mEdgeSwipesOffset[DragEdge.Left.ordinal()] = a.getDimension(R.styleable.SwipeLayout_leftEdgeSwipeOffset, 0); + mEdgeSwipesOffset[DragEdge.Right.ordinal()] = a.getDimension(R.styleable.SwipeLayout_rightEdgeSwipeOffset, 0); + mEdgeSwipesOffset[DragEdge.Top.ordinal()] = a.getDimension(R.styleable.SwipeLayout_topEdgeSwipeOffset, 0); + mEdgeSwipesOffset[DragEdge.Bottom.ordinal()] = a.getDimension(R.styleable.SwipeLayout_bottomEdgeSwipeOffset, 0); + setClickToClose(a.getBoolean(R.styleable.SwipeLayout_clickToClose, mClickToClose)); + + if ((dragEdgeChoices & DRAG_LEFT) == DRAG_LEFT) { + mDragEdges.put(DragEdge.Left, null); + } + if ((dragEdgeChoices & DRAG_TOP) == DRAG_TOP) { + mDragEdges.put(DragEdge.Top, null); + } + if ((dragEdgeChoices & DRAG_RIGHT) == DRAG_RIGHT) { + mDragEdges.put(DragEdge.Right, null); + } + if ((dragEdgeChoices & DRAG_BOTTOM) == DRAG_BOTTOM) { + mDragEdges.put(DragEdge.Bottom, null); + } + int ordinal = a.getInt(R.styleable.SwipeLayout_show_mode, ShowMode.PullOut.ordinal()); + mShowMode = ShowMode.values()[ordinal]; + a.recycle(); + + } + + public interface SwipeListener { + void onStartOpen(SwipeLayout layout); + + void onOpen(SwipeLayout layout); + + void onStartClose(SwipeLayout layout); + + void onClose(SwipeLayout layout); + + void onUpdate(SwipeLayout layout, int leftOffset, int topOffset); + + void onHandRelease(SwipeLayout layout, float xvel, float yvel); + } + + public void addSwipeListener(SwipeListener l) { + removeAllSwipeListener(); //保证一个View只有一个监听器 防止监听回调重复 + mSwipeListeners.add(l); + } + + public void removeSwipeListener(SwipeListener l) { + mSwipeListeners.remove(l); + } + + public void removeAllSwipeListener() { + mSwipeListeners.clear(); + } + + public interface SwipeDenier { + /* + * Called in onInterceptTouchEvent Determines if this swipe event should + * be denied Implement this interface if you are using views with swipe + * gestures As a child of SwipeLayout + * + * @return true deny false allow + */ + boolean shouldDenySwipe(MotionEvent ev); + } + + public void addSwipeDenier(SwipeDenier denier) { + mSwipeDeniers.add(denier); + } + + public void removeSwipeDenier(SwipeDenier denier) { + mSwipeDeniers.remove(denier); + } + + public void removeAllSwipeDeniers() { + mSwipeDeniers.clear(); + } + + public interface OnRevealListener { + void onReveal(View child, DragEdge edge, float fraction, int distance); + } + + /** + * bind a view with a specific + * {@link com.daimajia.swipe.SwipeLayout.OnRevealListener} + * + * @param childId the view id. + * @param l the target + * {@link com.daimajia.swipe.SwipeLayout.OnRevealListener} + */ + public void addRevealListener(int childId, OnRevealListener l) { + View child = findViewById(childId); + if (child == null) { + throw new IllegalArgumentException("Child does not belong to SwipeListener."); + } + + if (!mShowEntirely.containsKey(child)) { + mShowEntirely.put(child, false); + } + if (mRevealListeners.get(child) == null) + mRevealListeners.put(child, new ArrayList()); + + mRevealListeners.get(child).add(l); + } + + /** + * bind multiple views with an + * {@link com.daimajia.swipe.SwipeLayout.OnRevealListener}. + * + * @param childIds the view id. + * @param l the {@link com.daimajia.swipe.SwipeLayout.OnRevealListener} + */ + public void addRevealListener(int[] childIds, OnRevealListener l) { + for (int i : childIds) + addRevealListener(i, l); + } + + public void removeRevealListener(int childId, OnRevealListener l) { + View child = findViewById(childId); + + if (child == null) return; + + mShowEntirely.remove(child); + if (mRevealListeners.containsKey(child)) mRevealListeners.get(child).remove(l); + } + + public void removeAllRevealListeners(int childId) { + View child = findViewById(childId); + if (child != null) { + mRevealListeners.remove(child); + mShowEntirely.remove(child); + } + } + + private ViewDragHelper.Callback mDragHelperCallback = new ViewDragHelper.Callback() { + + @Override + public int clampViewPositionHorizontal(View child, int left, int dx) { + if (child == getSurfaceView()) { + switch (mCurrentDragEdge) { + case Top: + case Bottom: + return getPaddingLeft(); + case Left: + if (left < getPaddingLeft()) return getPaddingLeft(); + if (left > getPaddingLeft() + mDragDistance) + return getPaddingLeft() + mDragDistance; + break; + case Right: + if (left > getPaddingLeft()) return getPaddingLeft(); + if (left < getPaddingLeft() - mDragDistance) + return getPaddingLeft() - mDragDistance; + break; + } + } else if (getCurrentBottomView() == child) { + + switch (mCurrentDragEdge) { + case Top: + case Bottom: + return getPaddingLeft(); + case Left: + if (mShowMode == ShowMode.PullOut) { + if (left > getPaddingLeft()) return getPaddingLeft(); + } + break; + case Right: + if (mShowMode == ShowMode.PullOut) { + if (left < getMeasuredWidth() - mDragDistance) { + return getMeasuredWidth() - mDragDistance; + } + } + break; + } + } + return left; + } + + @Override + public int clampViewPositionVertical(View child, int top, int dy) { + if (child == getSurfaceView()) { + switch (mCurrentDragEdge) { + case Left: + case Right: + return getPaddingTop(); + case Top: + if (top < getPaddingTop()) return getPaddingTop(); + if (top > getPaddingTop() + mDragDistance) + return getPaddingTop() + mDragDistance; + break; + case Bottom: + if (top < getPaddingTop() - mDragDistance) { + return getPaddingTop() - mDragDistance; + } + if (top > getPaddingTop()) { + return getPaddingTop(); + } + } + } else { + View surfaceView = getSurfaceView(); + int surfaceViewTop = surfaceView == null ? 0 : surfaceView.getTop(); + switch (mCurrentDragEdge) { + case Left: + case Right: + return getPaddingTop(); + case Top: + if (mShowMode == ShowMode.PullOut) { + if (top > getPaddingTop()) return getPaddingTop(); + } else { + if (surfaceViewTop + dy < getPaddingTop()) + return getPaddingTop(); + if (surfaceViewTop + dy > getPaddingTop() + mDragDistance) + return getPaddingTop() + mDragDistance; + } + break; + case Bottom: + if (mShowMode == ShowMode.PullOut) { + if (top < getMeasuredHeight() - mDragDistance) + return getMeasuredHeight() - mDragDistance; + } else { + if (surfaceViewTop + dy >= getPaddingTop()) + return getPaddingTop(); + if (surfaceViewTop + dy <= getPaddingTop() - mDragDistance) + return getPaddingTop() - mDragDistance; + } + } + } + return top; + } + + @Override + public boolean tryCaptureView(View child, int pointerId) { + boolean result = child == getSurfaceView() || getBottomViews().contains(child); + if (result) { + isCloseBeforeDrag = getOpenStatus() == Status.Close; + } + return result; + } + + @Override + public int getViewHorizontalDragRange(View child) { + return mDragDistance; + } + + @Override + public int getViewVerticalDragRange(View child) { + return mDragDistance; + } + + boolean isCloseBeforeDrag = true; + + @Override + public void onViewReleased(View releasedChild, float xvel, float yvel) { + super.onViewReleased(releasedChild, xvel, yvel); + processHandRelease(xvel, yvel, isCloseBeforeDrag); + for (SwipeListener l : mSwipeListeners) { + l.onHandRelease(SwipeLayout.this, xvel, yvel); + } + + invalidate(); + } + + @Override + public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { + View surfaceView = getSurfaceView(); + if (surfaceView == null) return; + View currentBottomView = getCurrentBottomView(); + int evLeft = surfaceView.getLeft(), + evRight = surfaceView.getRight(), + evTop = surfaceView.getTop(), + evBottom = surfaceView.getBottom(); + if (changedView == surfaceView) { + + if (mShowMode == ShowMode.PullOut && currentBottomView != null) { + if (mCurrentDragEdge == DragEdge.Left || mCurrentDragEdge == DragEdge.Right) { + currentBottomView.offsetLeftAndRight(dx); + } else { + currentBottomView.offsetTopAndBottom(dy); + } + } + + } else if (getBottomViews().contains(changedView)) { + + if (mShowMode == ShowMode.PullOut) { + surfaceView.offsetLeftAndRight(dx); + surfaceView.offsetTopAndBottom(dy); + } else { + Rect rect = computeBottomLayDown(mCurrentDragEdge); + if (currentBottomView != null) { + currentBottomView.layout(rect.left, rect.top, rect.right, rect.bottom); + } + + int newLeft = surfaceView.getLeft() + dx, newTop = surfaceView.getTop() + dy; + + if (mCurrentDragEdge == DragEdge.Left && newLeft < getPaddingLeft()) + newLeft = getPaddingLeft(); + else if (mCurrentDragEdge == DragEdge.Right && newLeft > getPaddingLeft()) + newLeft = getPaddingLeft(); + else if (mCurrentDragEdge == DragEdge.Top && newTop < getPaddingTop()) + newTop = getPaddingTop(); + else if (mCurrentDragEdge == DragEdge.Bottom && newTop > getPaddingTop()) + newTop = getPaddingTop(); + + surfaceView.layout(newLeft, newTop, newLeft + getMeasuredWidth(), newTop + getMeasuredHeight()); + } + } + + dispatchRevealEvent(evLeft, evTop, evRight, evBottom); + + dispatchSwipeEvent(evLeft, evTop, dx, dy); + + invalidate(); + + captureChildrenBound(); + } + }; + + /** + * save children's bounds, so they can restore the bound in {@link #onLayout(boolean, int, int, int, int)} + */ + private void captureChildrenBound(){ + View currentBottomView = getCurrentBottomView(); + if(getOpenStatus()== Status.Close){ + mViewBoundCache.remove(currentBottomView); + return; + } + + View[] views = new View[]{getSurfaceView(), currentBottomView}; + for (View child : views) { + Rect rect = mViewBoundCache.get(child); + if(rect==null){ + rect = new Rect(); + mViewBoundCache.put(child, rect); + } + rect.left = child.getLeft(); + rect.top = child.getTop(); + rect.right = child.getRight(); + rect.bottom = child.getBottom(); + } + } + + /** + * the dispatchRevealEvent method may not always get accurate position, it + * makes the view may not always get the event when the view is totally + * show( fraction = 1), so , we need to calculate every time. + */ + protected boolean isViewTotallyFirstShowed(View child, Rect relativePosition, DragEdge edge, int surfaceLeft, + int surfaceTop, int surfaceRight, int surfaceBottom) { + if (mShowEntirely.get(child)) return false; + int childLeft = relativePosition.left; + int childRight = relativePosition.right; + int childTop = relativePosition.top; + int childBottom = relativePosition.bottom; + boolean r = false; + if (getShowMode() == ShowMode.LayDown) { + if ((edge == DragEdge.Right && surfaceRight <= childLeft) + || (edge == DragEdge.Left && surfaceLeft >= childRight) + || (edge == DragEdge.Top && surfaceTop >= childBottom) + || (edge == DragEdge.Bottom && surfaceBottom <= childTop)) r = true; + } else if (getShowMode() == ShowMode.PullOut) { + if ((edge == DragEdge.Right && childRight <= getWidth()) + || (edge == DragEdge.Left && childLeft >= getPaddingLeft()) + || (edge == DragEdge.Top && childTop >= getPaddingTop()) + || (edge == DragEdge.Bottom && childBottom <= getHeight())) r = true; + } + return r; + } + + protected boolean isViewShowing(View child, Rect relativePosition, DragEdge availableEdge, int surfaceLeft, + int surfaceTop, int surfaceRight, int surfaceBottom) { + int childLeft = relativePosition.left; + int childRight = relativePosition.right; + int childTop = relativePosition.top; + int childBottom = relativePosition.bottom; + if (getShowMode() == ShowMode.LayDown) { + switch (availableEdge) { + case Right: + if (surfaceRight > childLeft && surfaceRight <= childRight) { + return true; + } + break; + case Left: + if (surfaceLeft < childRight && surfaceLeft >= childLeft) { + return true; + } + break; + case Top: + if (surfaceTop >= childTop && surfaceTop < childBottom) { + return true; + } + break; + case Bottom: + if (surfaceBottom > childTop && surfaceBottom <= childBottom) { + return true; + } + break; + } + } else if (getShowMode() == ShowMode.PullOut) { + switch (availableEdge) { + case Right: + if (childLeft <= getWidth() && childRight > getWidth()) return true; + break; + case Left: + if (childRight >= getPaddingLeft() && childLeft < getPaddingLeft()) return true; + break; + case Top: + if (childTop < getPaddingTop() && childBottom >= getPaddingTop()) return true; + break; + case Bottom: + if (childTop < getHeight() && childTop >= getPaddingTop()) return true; + break; + } + } + return false; + } + + protected Rect getRelativePosition(View child) { + View t = child; + Rect r = new Rect(t.getLeft(), t.getTop(), 0, 0); + while (t.getParent() != null && t != getRootView()) { + t = (View) t.getParent(); + if (t == this) break; + r.left += t.getLeft(); + r.top += t.getTop(); + } + r.right = r.left + child.getMeasuredWidth(); + r.bottom = r.top + child.getMeasuredHeight(); + return r; + } + + private int mEventCounter = 0; + + protected void dispatchSwipeEvent(int surfaceLeft, int surfaceTop, int dx, int dy) { + Utils.log("=======dispatchSwipeEvent"); + DragEdge edge = getDragEdge(); + boolean open = true; + if (edge == DragEdge.Left) { + if (dx < 0) open = false; + } else if (edge == DragEdge.Right) { + if (dx > 0) open = false; + } else if (edge == DragEdge.Top) { + if (dy < 0) open = false; + } else if (edge == DragEdge.Bottom) { + if (dy > 0) open = false; + } + + dispatchSwipeEvent(surfaceLeft, surfaceTop, open); + } + + protected void dispatchSwipeEvent(int surfaceLeft, int surfaceTop, boolean open) { + safeBottomView(); + Status status = getOpenStatus(); + + if (!mSwipeListeners.isEmpty()) { + mEventCounter++; + for (SwipeListener l : mSwipeListeners) { + if (mEventCounter == 1) { + if (open) { + l.onStartOpen(this); + } else { + l.onStartClose(this); + } + } + l.onUpdate(SwipeLayout.this, surfaceLeft - getPaddingLeft(), surfaceTop - getPaddingTop()); + } + + if (status == Status.Close) { + for (SwipeListener l : mSwipeListeners) { + l.onClose(SwipeLayout.this); + } + mEventCounter = 0; + } + + if (status == Status.Open) { + View currentBottomView = getCurrentBottomView(); + if (currentBottomView != null) { + currentBottomView.setEnabled(true); + } + for (SwipeListener l : mSwipeListeners) { + l.onOpen(SwipeLayout.this); + } + mEventCounter = 0; + } + } + } + + /** + * prevent bottom view get any touch event. Especially in LayDown mode. + */ + private void safeBottomView() { + Status status = getOpenStatus(); + List bottoms = getBottomViews(); + + if (status == Status.Close) { + for (View bottom : bottoms) { + if (bottom != null && bottom.getVisibility() != INVISIBLE) { + bottom.setVisibility(INVISIBLE); + } + } + } else { + View currentBottomView = getCurrentBottomView(); + if (currentBottomView != null && currentBottomView.getVisibility() != VISIBLE) { + currentBottomView.setVisibility(VISIBLE); + } + } + } + + protected void dispatchRevealEvent(final int surfaceLeft, final int surfaceTop, final int surfaceRight, + final int surfaceBottom) { + if (mRevealListeners.isEmpty()) return; + for (Map.Entry> entry : mRevealListeners.entrySet()) { + View child = entry.getKey(); + Rect rect = getRelativePosition(child); + if (isViewShowing(child, rect, mCurrentDragEdge, surfaceLeft, surfaceTop, + surfaceRight, surfaceBottom)) { + mShowEntirely.put(child, false); + int distance = 0; + float fraction = 0f; + if (getShowMode() == ShowMode.LayDown) { + switch (mCurrentDragEdge) { + case Left: + distance = rect.left - surfaceLeft; + fraction = distance / (float) child.getWidth(); + break; + case Right: + distance = rect.right - surfaceRight; + fraction = distance / (float) child.getWidth(); + break; + case Top: + distance = rect.top - surfaceTop; + fraction = distance / (float) child.getHeight(); + break; + case Bottom: + distance = rect.bottom - surfaceBottom; + fraction = distance / (float) child.getHeight(); + break; + } + } else if (getShowMode() == ShowMode.PullOut) { + switch (mCurrentDragEdge) { + case Left: + distance = rect.right - getPaddingLeft(); + fraction = distance / (float) child.getWidth(); + break; + case Right: + distance = rect.left - getWidth(); + fraction = distance / (float) child.getWidth(); + break; + case Top: + distance = rect.bottom - getPaddingTop(); + fraction = distance / (float) child.getHeight(); + break; + case Bottom: + distance = rect.top - getHeight(); + fraction = distance / (float) child.getHeight(); + break; + } + } + + for (OnRevealListener l : entry.getValue()) { + l.onReveal(child, mCurrentDragEdge, Math.abs(fraction), distance); + if (Math.abs(fraction) == 1) { + mShowEntirely.put(child, true); + } + } + } + + if (isViewTotallyFirstShowed(child, rect, mCurrentDragEdge, surfaceLeft, surfaceTop, + surfaceRight, surfaceBottom)) { + mShowEntirely.put(child, true); + for (OnRevealListener l : entry.getValue()) { + if (mCurrentDragEdge == DragEdge.Left + || mCurrentDragEdge == DragEdge.Right) + l.onReveal(child, mCurrentDragEdge, 1, child.getWidth()); + else + l.onReveal(child, mCurrentDragEdge, 1, child.getHeight()); + } + } + + } + } + + @Override + public void computeScroll() { + super.computeScroll(); + if (mDragHelper.continueSettling(true)) { + ViewCompat.postInvalidateOnAnimation(this); + } + } + + /** + * {@link OnLayoutChangeListener} added in API 11. I need + * to support it from API 8. + */ + public interface OnLayout { + void onLayout(SwipeLayout v); + } + + private List mOnLayoutListeners; + + public void addOnLayoutListener(OnLayout l) { + if (mOnLayoutListeners == null) mOnLayoutListeners = new ArrayList(); + mOnLayoutListeners.add(l); + } + + public void removeOnLayoutListener(OnLayout l) { + if (mOnLayoutListeners != null) mOnLayoutListeners.remove(l); + } + + public void clearDragEdge() { + mDragEdges.clear(); + } + + public void setDrag(DragEdge dragEdge, int childId) { + clearDragEdge(); + addDrag(dragEdge, childId); + } + + public void setDrag(DragEdge dragEdge, View child) { + clearDragEdge(); + addDrag(dragEdge, child); + } + + public void addDrag(DragEdge dragEdge, int childId) { + addDrag(dragEdge, findViewById(childId), null); + } + + public void addDrag(DragEdge dragEdge, View child) { + addDrag(dragEdge, child, null); + } + + public void addDrag(DragEdge dragEdge, View child, ViewGroup.LayoutParams params) { + if (child == null) return; + + if (params == null) { + params = generateDefaultLayoutParams(); + } + if (!checkLayoutParams(params)) { + params = generateLayoutParams(params); + } + int gravity = -1; + switch (dragEdge) { + case Left: + gravity = Gravity.LEFT; + break; + case Right: + gravity = Gravity.RIGHT; + break; + case Top: + gravity = Gravity.TOP; + break; + case Bottom: + gravity = Gravity.BOTTOM; + break; + } + if (params instanceof LayoutParams) { + ((LayoutParams) params).gravity = gravity; + } + addView(child, 0, params); + } + + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + if (child == null) return; + int gravity = Gravity.NO_GRAVITY; + try { + gravity = (Integer) params.getClass().getField("gravity").get(params); + } catch (Exception e) { + e.printStackTrace(); + } + + if (gravity > 0) { + gravity = GravityCompat.getAbsoluteGravity(gravity, ViewCompat.getLayoutDirection(this)); + + if ((gravity & Gravity.LEFT) == Gravity.LEFT) { + mDragEdges.put(DragEdge.Left, child); + } + if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) { + mDragEdges.put(DragEdge.Right, child); + } + if ((gravity & Gravity.TOP) == Gravity.TOP) { + mDragEdges.put(DragEdge.Top, child); + } + if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) { + mDragEdges.put(DragEdge.Bottom, child); + } + } else { + for (Map.Entry entry : mDragEdges.entrySet()) { + if (entry.getValue() == null) { + //means used the drag_edge attr, the no gravity child should be use set + mDragEdges.put(entry.getKey(), child); + break; + } + } + } + if (child.getParent() == this) { + return; + } + super.addView(child, index, params); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + updateBottomViews(); + + if (mOnLayoutListeners != null) for (int i = 0; i < mOnLayoutListeners.size(); i++) { + mOnLayoutListeners.get(i).onLayout(this); + } + } + + void layoutPullOut() { + View surfaceView = getSurfaceView(); + Rect surfaceRect = mViewBoundCache.get(surfaceView); + if(surfaceRect == null) surfaceRect = computeSurfaceLayoutArea(false); + if (surfaceView != null) { + surfaceView.layout(surfaceRect.left, surfaceRect.top, surfaceRect.right, surfaceRect.bottom); + bringChildToFront(surfaceView); + } + View currentBottomView = getCurrentBottomView(); + Rect bottomViewRect = mViewBoundCache.get(currentBottomView); + if(bottomViewRect == null) bottomViewRect = computeBottomLayoutAreaViaSurface(ShowMode.PullOut, surfaceRect); + if (currentBottomView != null) { + currentBottomView.layout(bottomViewRect.left, bottomViewRect.top, bottomViewRect.right, bottomViewRect.bottom); + } + } + + void layoutLayDown() { + View surfaceView = getSurfaceView(); + Rect surfaceRect = mViewBoundCache.get(surfaceView); + if(surfaceRect == null) surfaceRect = computeSurfaceLayoutArea(false); + if (surfaceView != null) { + surfaceView.layout(surfaceRect.left, surfaceRect.top, surfaceRect.right, surfaceRect.bottom); + bringChildToFront(surfaceView); + } + View currentBottomView = getCurrentBottomView(); + Rect bottomViewRect = mViewBoundCache.get(currentBottomView); + if(bottomViewRect == null) bottomViewRect = computeBottomLayoutAreaViaSurface(ShowMode.LayDown, surfaceRect); + if (currentBottomView != null) { + currentBottomView.layout(bottomViewRect.left, bottomViewRect.top, bottomViewRect.right, bottomViewRect.bottom); + } + } + + private boolean mIsBeingDragged; + + private void checkCanDrag(MotionEvent ev) { + if (mIsBeingDragged) return; + if (getOpenStatus() == Status.Middle) { + mIsBeingDragged = true; + return; + } + Status status = getOpenStatus(); + float distanceX = ev.getRawX() - sX; + float distanceY = ev.getRawY() - sY; + float angle = Math.abs(distanceY / distanceX); + angle = (float) Math.toDegrees(Math.atan(angle)); + if (getOpenStatus() == Status.Close) { + DragEdge dragEdge; + if (angle < 45) { + if (distanceX > 0 && isLeftSwipeEnabled()) { + dragEdge = DragEdge.Left; + } else if (distanceX < 0 && isRightSwipeEnabled()) { + dragEdge = DragEdge.Right; + } else return; + + } else { + if (distanceY > 0 && isTopSwipeEnabled()) { + dragEdge = DragEdge.Top; + } else if (distanceY < 0 && isBottomSwipeEnabled()) { + dragEdge = DragEdge.Bottom; + } else return; + } + setCurrentDragEdge(dragEdge); + } + + boolean doNothing = false; + if (mCurrentDragEdge == DragEdge.Right) { + boolean suitable = (status == Status.Open && distanceX > mTouchSlop) + || (status == Status.Close && distanceX < -mTouchSlop); + suitable = suitable || (status == Status.Middle); + + if (angle > 30 || !suitable) { + doNothing = true; + } + } + + if (mCurrentDragEdge == DragEdge.Left) { + boolean suitable = (status == Status.Open && distanceX < -mTouchSlop) + || (status == Status.Close && distanceX > mTouchSlop); + suitable = suitable || status == Status.Middle; + + if (angle > 30 || !suitable) { + doNothing = true; + } + } + + if (mCurrentDragEdge == DragEdge.Top) { + boolean suitable = (status == Status.Open && distanceY < -mTouchSlop) + || (status == Status.Close && distanceY > mTouchSlop); + suitable = suitable || status == Status.Middle; + + if (angle < 60 || !suitable) { + doNothing = true; + } + } + + if (mCurrentDragEdge == DragEdge.Bottom) { + boolean suitable = (status == Status.Open && distanceY > mTouchSlop) + || (status == Status.Close && distanceY < -mTouchSlop); + suitable = suitable || status == Status.Middle; + + if (angle < 60 || !suitable) { + doNothing = true; + } + } + mIsBeingDragged = !doNothing; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (!isSwipeEnabled()) { + return false; + } + if (mClickToClose && getOpenStatus() == Status.Open && isTouchOnSurface(ev)) { + return true; + } + for (SwipeDenier denier : mSwipeDeniers) { + if (denier != null && denier.shouldDenySwipe(ev)) { + return false; + } + } + + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN: + mDragHelper.processTouchEvent(ev); + mIsBeingDragged = false; + sX = ev.getRawX(); + sY = ev.getRawY(); + //if the swipe is in middle state(scrolling), should intercept the touch + if (getOpenStatus() == Status.Middle) { + mIsBeingDragged = true; + } + break; + case MotionEvent.ACTION_MOVE: + boolean beforeCheck = mIsBeingDragged; + checkCanDrag(ev); + if (mIsBeingDragged) { + ViewParent parent = getParent(); + if (parent != null) { + parent.requestDisallowInterceptTouchEvent(true); + } + } + if (!beforeCheck && mIsBeingDragged) { + //let children has one chance to catch the touch, and request the swipe not intercept + //useful when swipeLayout wrap a swipeLayout or other gestural layout + return false; + } + break; + + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + mIsBeingDragged = false; + mDragHelper.processTouchEvent(ev); + break; + default://handle other action, such as ACTION_POINTER_DOWN/UP + mDragHelper.processTouchEvent(ev); + } + return mIsBeingDragged; + } + + private float sX = -1, sY = -1; + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (!isSwipeEnabled()) return super.onTouchEvent(event); + + int action = event.getActionMasked(); + gestureDetector.onTouchEvent(event); + + switch (action) { + case MotionEvent.ACTION_DOWN: + mDragHelper.processTouchEvent(event); + sX = event.getRawX(); + sY = event.getRawY(); + + + case MotionEvent.ACTION_MOVE: { + //the drag state and the direction are already judged at onInterceptTouchEvent + checkCanDrag(event); + if (mIsBeingDragged) { + getParent().requestDisallowInterceptTouchEvent(true); + mDragHelper.processTouchEvent(event); + } + break; + } + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + mIsBeingDragged = false; + mDragHelper.processTouchEvent(event); + break; + + default://handle other action, such as ACTION_POINTER_DOWN/UP + mDragHelper.processTouchEvent(event); + } + + return super.onTouchEvent(event) || mIsBeingDragged || action == MotionEvent.ACTION_DOWN; + } + + public boolean isClickToClose() { + return mClickToClose; + } + + public void setClickToClose(boolean mClickToClose) { + this.mClickToClose = mClickToClose; + } + + public void setSwipeEnabled(boolean enabled) { + mSwipeEnabled = enabled; + } + + public boolean isSwipeEnabled() { + return mSwipeEnabled; + } + + public boolean isLeftSwipeEnabled() { + View bottomView = mDragEdges.get(DragEdge.Left); + return bottomView != null && bottomView.getParent() == this + && bottomView != getSurfaceView() && mSwipesEnabled[DragEdge.Left.ordinal()]; + } + + public void setLeftSwipeEnabled(boolean leftSwipeEnabled) { + this.mSwipesEnabled[DragEdge.Left.ordinal()] = leftSwipeEnabled; + } + + public boolean isRightSwipeEnabled() { + View bottomView = mDragEdges.get(DragEdge.Right); + return bottomView != null && bottomView.getParent() == this + && bottomView != getSurfaceView() && mSwipesEnabled[DragEdge.Right.ordinal()]; + } + + public void setRightSwipeEnabled(boolean rightSwipeEnabled) { + this.mSwipesEnabled[DragEdge.Right.ordinal()] = rightSwipeEnabled; + } + + public boolean isTopSwipeEnabled() { + View bottomView = mDragEdges.get(DragEdge.Top); + return bottomView != null && bottomView.getParent() == this + && bottomView != getSurfaceView() && mSwipesEnabled[DragEdge.Top.ordinal()]; + } + + public void setTopSwipeEnabled(boolean topSwipeEnabled) { + this.mSwipesEnabled[DragEdge.Top.ordinal()] = topSwipeEnabled; + } + + public boolean isBottomSwipeEnabled() { + View bottomView = mDragEdges.get(DragEdge.Bottom); + return bottomView != null && bottomView.getParent() == this + && bottomView != getSurfaceView() && mSwipesEnabled[DragEdge.Bottom.ordinal()]; + } + + public void setBottomSwipeEnabled(boolean bottomSwipeEnabled) { + this.mSwipesEnabled[DragEdge.Bottom.ordinal()] = bottomSwipeEnabled; + } + /*** + * Returns the percentage of revealing at which the view below should the view finish opening + * if it was already open before dragging + * @returns The percentage of view revealed to trigger, default value is 0.25 + */ + public float getWillOpenPercentAfterOpen() { + return mWillOpenPercentAfterOpen; + } + + /*** + * Allows to stablish at what percentage of revealing the view below should the view finish opening + * if it was already open before dragging + * @param willOpenPercentAfterOpen The percentage of view revealed to trigger, default value is 0.25 + */ + public void setWillOpenPercentAfterOpen(float willOpenPercentAfterOpen) { + this.mWillOpenPercentAfterOpen = willOpenPercentAfterOpen; + } + /*** + * Returns the percentage of revealing at which the view below should the view finish opening + * if it was already closed before dragging + * @returns The percentage of view revealed to trigger, default value is 0.25 + */ + public float getWillOpenPercentAfterClose() { + return mWillOpenPercentAfterClose; + } + /*** + * Allows to stablish at what percentage of revealing the view below should the view finish opening + * if it was already closed before dragging + * @param willOpenPercentAfterClose The percentage of view revealed to trigger, default value is 0.75 + */ + public void setWillOpenPercentAfterClose(float willOpenPercentAfterClose) { + this.mWillOpenPercentAfterClose = willOpenPercentAfterClose; + } + + private boolean insideAdapterView() { + return getAdapterView() != null; + } + + private AdapterView getAdapterView() { + ViewParent t = getParent(); + if (t instanceof AdapterView) { + return (AdapterView) t; + } + return null; + } + + private void performAdapterViewItemClick() { + if (getOpenStatus() != Status.Close) return; + ViewParent t = getParent(); + if (t instanceof AdapterView) { + AdapterView view = (AdapterView) t; + int p = view.getPositionForView(SwipeLayout.this); + if (p != AdapterView.INVALID_POSITION) { + view.performItemClick(view.getChildAt(p - view.getFirstVisiblePosition()), p, view + .getAdapter().getItemId(p)); + } + } + } + + private boolean performAdapterViewItemLongClick() { + if (getOpenStatus() != Status.Close) return false; + ViewParent t = getParent(); + if (t instanceof AdapterView) { + AdapterView view = (AdapterView) t; + int p = view.getPositionForView(SwipeLayout.this); + if (p == AdapterView.INVALID_POSITION) return false; + long vId = view.getItemIdAtPosition(p); + boolean handled = false; + try { + Method m = AbsListView.class.getDeclaredMethod("performLongPress", View.class, int.class, long.class); + m.setAccessible(true); + handled = (boolean) m.invoke(view, SwipeLayout.this, p, vId); + + } catch (Exception e) { + e.printStackTrace(); + + if (view.getOnItemLongClickListener() != null) { + handled = view.getOnItemLongClickListener().onItemLongClick(view, SwipeLayout.this, p, vId); + } + if (handled) { + view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + } + } + return handled; + } + return false; + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (insideAdapterView()) { + if (clickListener == null) { + setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + performAdapterViewItemClick(); + } + }); + } + if (longClickListener == null) { + setOnLongClickListener(new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + performAdapterViewItemLongClick(); + return true; + } + }); + } + } + } + + OnClickListener clickListener; + + @Override + public void setOnClickListener(OnClickListener l) { + super.setOnClickListener(l); + clickListener = l; + } + + OnLongClickListener longClickListener; + + @Override + public void setOnLongClickListener(OnLongClickListener l) { + super.setOnLongClickListener(l); + longClickListener = l; + } + + private Rect hitSurfaceRect; + + private boolean isTouchOnSurface(MotionEvent ev) { + View surfaceView = getSurfaceView(); + if (surfaceView == null) { + return false; + } + if (hitSurfaceRect == null) { + hitSurfaceRect = new Rect(); + } + surfaceView.getHitRect(hitSurfaceRect); + return hitSurfaceRect.contains((int) ev.getX(), (int) ev.getY()); + } + + private GestureDetector gestureDetector = new GestureDetector(getContext(), new SwipeDetector()); + + class SwipeDetector extends GestureDetector.SimpleOnGestureListener { + @Override + public boolean onSingleTapUp(MotionEvent e) { + if (mClickToClose && isTouchOnSurface(e)) { + close(); + } + return super.onSingleTapUp(e); + } + + @Override + public boolean onDoubleTap(MotionEvent e) { + if (mDoubleClickListener != null) { + View target; + View bottom = getCurrentBottomView(); + View surface = getSurfaceView(); + if (bottom != null && e.getX() > bottom.getLeft() && e.getX() < bottom.getRight() + && e.getY() > bottom.getTop() && e.getY() < bottom.getBottom()) { + target = bottom; + } else { + target = surface; + } + mDoubleClickListener.onDoubleClick(SwipeLayout.this, target == surface); + } + return true; + } + } + + /** + * set the drag distance, it will force set the bottom view's width or + * height via this value. + * + * @param max max distance in dp unit + */ + public void setDragDistance(int max) { + if (max < 0) max = 0; + mDragDistance = dp2px(max); + requestLayout(); + } + + /** + * There are 2 diffirent show mode. + * {@link com.daimajia.swipe.SwipeLayout.ShowMode}.PullOut and + * {@link com.daimajia.swipe.SwipeLayout.ShowMode}.LayDown. + * + * @param mode + */ + public void setShowMode(ShowMode mode) { + mShowMode = mode; + requestLayout(); + } + + public DragEdge getDragEdge() { + return mCurrentDragEdge; + } + + public int getDragDistance() { + return mDragDistance; + } + + public ShowMode getShowMode() { + return mShowMode; + } + + /** + * return null if there is no surface view(no children) + */ + public View getSurfaceView() { + if (getChildCount() == 0) return null; + return getChildAt(getChildCount() - 1); + } + + /** + * return null if there is no bottom view + */ + @Nullable + public View getCurrentBottomView() { + List bottoms = getBottomViews(); + if (mCurrentDragEdge.ordinal() < bottoms.size()) { + return bottoms.get(mCurrentDragEdge.ordinal()); + } + return null; + } + + /** + * @return all bottomViews: left, top, right, bottom (may null if the edge is not set) + */ + public List getBottomViews() { + ArrayList bottoms = new ArrayList(); + for (DragEdge dragEdge : DragEdge.values()) { + bottoms.add(mDragEdges.get(dragEdge)); + } + return bottoms; + } + + public enum Status { + Middle, + Open, + Close + } + + /** + * get the open status. + * + * @return {@link com.daimajia.swipe.SwipeLayout.Status} Open , Close or + * Middle. + */ + public Status getOpenStatus() { + View surfaceView = getSurfaceView(); + if (surfaceView == null) { + return Status.Close; + } + int surfaceLeft = surfaceView.getLeft(); + int surfaceTop = surfaceView.getTop(); + if (surfaceLeft == getPaddingLeft() && surfaceTop == getPaddingTop()) return Status.Close; + + if (surfaceLeft == (getPaddingLeft() - mDragDistance) || surfaceLeft == (getPaddingLeft() + mDragDistance) + || surfaceTop == (getPaddingTop() - mDragDistance) || surfaceTop == (getPaddingTop() + mDragDistance)) + return Status.Open; + + return Status.Middle; + } + + + /** + * Process the surface release event. + * + * @param xvel xVelocity + * @param yvel yVelocity + * @param isCloseBeforeDragged the open state before drag + */ + protected void processHandRelease(float xvel, float yvel, boolean isCloseBeforeDragged) { + float minVelocity = mDragHelper.getMinVelocity(); + View surfaceView = getSurfaceView(); + DragEdge currentDragEdge = mCurrentDragEdge; + if (currentDragEdge == null || surfaceView == null) { + return; + } + + float willOpenPercent; + if (isCloseBeforeDragged) { + willOpenPercent = mWillOpenPercentAfterClose; + } else { + willOpenPercent = mWillOpenPercentAfterOpen; + } + + if (currentDragEdge == DragEdge.Left) { +// if (xvel > minVelocity) open(); //TODO 打开侧滑不受侧滑限制 +// else + if (xvel < -minVelocity) close(); + else { + float openPercent = 1f * getSurfaceView().getLeft() / mDragDistance; + if (openPercent > willOpenPercent) open(); + else close(); + } + } else if (currentDragEdge == DragEdge.Right) { + if (xvel > minVelocity) close(); + else if (xvel < -minVelocity) open(); + else { + float openPercent = 1f * (-getSurfaceView().getLeft()) / mDragDistance; + if (openPercent > willOpenPercent) open(); + else close(); + } + } else if (currentDragEdge == DragEdge.Top) { + if (yvel > minVelocity) open(); + else if (yvel < -minVelocity) close(); + else { + float openPercent = 1f * getSurfaceView().getTop() / mDragDistance; + if (openPercent > willOpenPercent) open(); + else close(); + } + } else if (currentDragEdge == DragEdge.Bottom) { + if (yvel > minVelocity) close(); + else if (yvel < -minVelocity) open(); + else { + float openPercent = 1f * (-getSurfaceView().getTop()) / mDragDistance; + if (openPercent > willOpenPercent) open(); + else close(); + } + } + } + + /** + * smoothly open surface. + */ + public void open() { + open(true, true); + } + + public void open(boolean smooth) { + open(smooth, true); + } + + public void open(boolean smooth, boolean notify) { + View surface = getSurfaceView(), bottom = getCurrentBottomView(); + if (surface == null) { + return; + } + int dx, dy; + Rect rect = computeSurfaceLayoutArea(true); + if (smooth) { + mDragHelper.smoothSlideViewTo(surface, rect.left, rect.top); + } else { + dx = rect.left - surface.getLeft(); + dy = rect.top - surface.getTop(); + surface.layout(rect.left, rect.top, rect.right, rect.bottom); + if (getShowMode() == ShowMode.PullOut) { + Rect bRect = computeBottomLayoutAreaViaSurface(ShowMode.PullOut, rect); + if (bottom != null) { + bottom.layout(bRect.left, bRect.top, bRect.right, bRect.bottom); + } + } + if (notify) { + dispatchRevealEvent(rect.left, rect.top, rect.right, rect.bottom); + dispatchSwipeEvent(rect.left, rect.top, dx, dy); + } else { + safeBottomView(); + } + } + invalidate(); + } + + public void open(DragEdge edge) { + setCurrentDragEdge(edge); + open(true, true); + } + + public void open(boolean smooth, DragEdge edge) { + setCurrentDragEdge(edge); + open(smooth, true); + } + + public void open(boolean smooth, boolean notify, DragEdge edge) { + setCurrentDragEdge(edge); + open(smooth, notify); + } + + /** + * smoothly close surface. + */ + public void close() { + close(true, true); + } + + public void close(boolean smooth) { + close(smooth, true); + } + + /** + * close surface + * + * @param smooth smoothly or not. + * @param notify if notify all the listeners. + */ + public void close(boolean smooth, boolean notify) { + View surface = getSurfaceView(); + if (surface == null) { + return; + } + int dx, dy; + if (smooth) + mDragHelper.smoothSlideViewTo(getSurfaceView(), getPaddingLeft(), getPaddingTop()); + else { + Rect rect = computeSurfaceLayoutArea(false); + dx = rect.left - surface.getLeft(); + dy = rect.top - surface.getTop(); + surface.layout(rect.left, rect.top, rect.right, rect.bottom); + if (notify) { + dispatchRevealEvent(rect.left, rect.top, rect.right, rect.bottom); + dispatchSwipeEvent(rect.left, rect.top, dx, dy); + } else { + safeBottomView(); + } + } + invalidate(); + } + + public void toggle() { + toggle(true); + } + + public void toggle(boolean smooth) { + if (getOpenStatus() == Status.Open) + close(smooth); + else if (getOpenStatus() == Status.Close) open(smooth); + } + + + /** + * a helper function to compute the Rect area that surface will hold in. + * + * @param open open status or close status. + */ + private Rect computeSurfaceLayoutArea(boolean open) { + int l = getPaddingLeft(), t = getPaddingTop(); + if (open) { + if (mCurrentDragEdge == DragEdge.Left) + l = getPaddingLeft() + mDragDistance; + else if (mCurrentDragEdge == DragEdge.Right) + l = getPaddingLeft() - mDragDistance; + else if (mCurrentDragEdge == DragEdge.Top) + t = getPaddingTop() + mDragDistance; + else t = getPaddingTop() - mDragDistance; + } + return new Rect(l, t, l + getMeasuredWidth(), t + getMeasuredHeight()); + } + + private Rect computeBottomLayoutAreaViaSurface(ShowMode mode, Rect surfaceArea) { + Rect rect = surfaceArea; + View bottomView = getCurrentBottomView(); + + int bl = rect.left, bt = rect.top, br = rect.right, bb = rect.bottom; + if (mode == ShowMode.PullOut) { + if (mCurrentDragEdge == DragEdge.Left) + bl = rect.left - mDragDistance; + else if (mCurrentDragEdge == DragEdge.Right) + bl = rect.right; + else if (mCurrentDragEdge == DragEdge.Top) + bt = rect.top - mDragDistance; + else bt = rect.bottom; + + if (mCurrentDragEdge == DragEdge.Left || mCurrentDragEdge == DragEdge.Right) { + bb = rect.bottom; + br = bl + (bottomView == null ? 0 : bottomView.getMeasuredWidth()); + } else { + bb = bt + (bottomView == null ? 0 : bottomView.getMeasuredHeight()); + br = rect.right; + } + } else if (mode == ShowMode.LayDown) { + if (mCurrentDragEdge == DragEdge.Left) + br = bl + mDragDistance; + else if (mCurrentDragEdge == DragEdge.Right) + bl = br - mDragDistance; + else if (mCurrentDragEdge == DragEdge.Top) + bb = bt + mDragDistance; + else bt = bb - mDragDistance; + + } + return new Rect(bl, bt, br, bb); + + } + + private Rect computeBottomLayDown(DragEdge dragEdge) { + int bl = getPaddingLeft(), bt = getPaddingTop(); + int br, bb; + if (dragEdge == DragEdge.Right) { + bl = getMeasuredWidth() - mDragDistance; + } else if (dragEdge == DragEdge.Bottom) { + bt = getMeasuredHeight() - mDragDistance; + } + if (dragEdge == DragEdge.Left || dragEdge == DragEdge.Right) { + br = bl + mDragDistance; + bb = bt + getMeasuredHeight(); + } else { + br = bl + getMeasuredWidth(); + bb = bt + mDragDistance; + } + return new Rect(bl, bt, br, bb); + } + + public void setOnDoubleClickListener(DoubleClickListener doubleClickListener) { + mDoubleClickListener = doubleClickListener; + } + + public interface DoubleClickListener { + void onDoubleClick(SwipeLayout layout, boolean surface); + } + + private int dp2px(float dp) { + return (int) (dp * getContext().getResources().getDisplayMetrics().density + 0.5f); + } + + + /** + * Deprecated, use {@link #setDrag(DragEdge, View)} + */ + @Deprecated + public void setDragEdge(DragEdge dragEdge) { + clearDragEdge(); + if (getChildCount() >= 2) { + mDragEdges.put(dragEdge, getChildAt(getChildCount() - 2)); + } + setCurrentDragEdge(dragEdge); + } + + @SuppressLint("Override") + protected void onViewRemoved(View child) { + for (Map.Entry entry : new HashMap(mDragEdges).entrySet()) { + if (entry.getValue() == child) { + mDragEdges.remove(entry.getKey()); + } + } + } + + public Map getDragEdgeMap() { + return mDragEdges; + } + + /** + * Deprecated, use {@link #getDragEdgeMap()} + */ + @Deprecated + public List getDragEdges() { + return new ArrayList(mDragEdges.keySet()); + } + + /** + * Deprecated, use {@link #setDrag(DragEdge, View)} + */ + @Deprecated + public void setDragEdges(List dragEdges) { + clearDragEdge(); + for (int i = 0, size = Math.min(dragEdges.size(), getChildCount() - 1); i < size; i++) { + DragEdge dragEdge = dragEdges.get(i); + mDragEdges.put(dragEdge, getChildAt(i)); + } + if (dragEdges.size() == 0 || dragEdges.contains(DefaultDragEdge)) { + setCurrentDragEdge(DefaultDragEdge); + } else { + setCurrentDragEdge(dragEdges.get(0)); + } + } + + /** + * Deprecated, use {@link #addDrag(DragEdge, View)} + */ + @Deprecated + public void setDragEdges(DragEdge... mDragEdges) { + clearDragEdge(); + setDragEdges(Arrays.asList(mDragEdges)); + } + + /** + * Deprecated, use {@link #addDrag(DragEdge, View)} + * When using multiple drag edges it's a good idea to pass the ids of the views that + * you're using for the left, right, top bottom views (-1 if you're not using a particular view) + */ + @Deprecated + public void setBottomViewIds(int leftId, int rightId, int topId, int bottomId) { + addDrag(DragEdge.Left, findViewById(leftId)); + addDrag(DragEdge.Right, findViewById(rightId)); + addDrag(DragEdge.Top, findViewById(topId)); + addDrag(DragEdge.Bottom, findViewById(bottomId)); + } + + private float getCurrentOffset() { + if (mCurrentDragEdge == null) return 0; + return mEdgeSwipesOffset[mCurrentDragEdge.ordinal()]; + } + + private void setCurrentDragEdge(DragEdge dragEdge) { + mCurrentDragEdge = dragEdge; + updateBottomViews(); + } + + private void updateBottomViews() { + View currentBottomView = getCurrentBottomView(); + if (currentBottomView != null) { + if (mCurrentDragEdge == DragEdge.Left || mCurrentDragEdge == DragEdge.Right) { + mDragDistance = currentBottomView.getMeasuredWidth() - dp2px(getCurrentOffset()); + } else { + mDragDistance = currentBottomView.getMeasuredHeight() - dp2px(getCurrentOffset()); + } + } + + if (mShowMode == ShowMode.PullOut) { + layoutPullOut(); + } else if (mShowMode == ShowMode.LayDown) { + layoutLayDown(); + } + + safeBottomView(); + } +} diff --git a/app/src/main/java/com/gh/gamecenter/ChooseReceiverActivity.java b/app/src/main/java/com/gh/gamecenter/ChooseReceiverActivity.java index a5c512ba9e..1b445416a0 100644 --- a/app/src/main/java/com/gh/gamecenter/ChooseReceiverActivity.java +++ b/app/src/main/java/com/gh/gamecenter/ChooseReceiverActivity.java @@ -20,6 +20,7 @@ import com.gh.base.AppController; import com.gh.base.BaseActivity; import com.gh.common.constant.Config; import com.gh.common.util.DialogUtils; +import com.gh.common.util.UserIconUtils; import com.gh.common.util.Utils; import com.gh.gamecenter.kuaichuan.BaseTransfer; import com.gh.gamecenter.kuaichuan.Constant; @@ -35,7 +36,9 @@ import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.util.HashMap; import java.util.List; +import java.util.Map; import butterknife.BindView; import butterknife.OnClick; @@ -53,6 +56,10 @@ public class ChooseReceiverActivity extends BaseActivity implements View.OnClick @BindView(R.id.choosereceiver_user2) LinearLayout choosereceiver_user2; @BindView(R.id.choosereceiver_user3) LinearLayout choosereceiver_user3; @BindView(R.id.choosereceiver_user4) LinearLayout choosereceiver_user4; + @BindView(R.id.choosereceiver_user1_icon) SimpleDraweeView userIcon1; + @BindView(R.id.choosereceiver_user2_icon) SimpleDraweeView userIcon2; + @BindView(R.id.choosereceiver_user3_icon) SimpleDraweeView userIcon3; + @BindView(R.id.choosereceiver_user4_icon) SimpleDraweeView userIcon4; @BindView(R.id.scan_gif) SimpleDraweeView mScanGif; @BindView(R.id.scan_user) TextView mScanUser; @BindView(R.id.scan_user_des) TextView mScanUserDes; @@ -65,7 +72,9 @@ public class ChooseReceiverActivity extends BaseActivity implements View.OnClick private boolean isStopScan; - private boolean isConnSuccess; + private boolean isDestroy; + + private int conUserIconTag; private SharedPreferences sp; @@ -98,13 +107,14 @@ public class ChooseReceiverActivity extends BaseActivity implements View.OnClick @OnClick(R.id.scan_hint) public void onScanHintListener() { - DialogUtils.showHintDialog(this, "对方操作步骤", "1.掏出手机,打开光环助手 " + - "\n2.在首页点击左上角,进去下载管理 \n3.点击“零流量传送”,在点击“我要接收”", + DialogUtils.showHintDialog(this, "请告诉你的好友这样操作:", "1.拿出手机,打开光环助手 " + + "\n2.点击首页左上角,进入下载管理 \n3.点击“零流量传送”,再点击“我要接收”", "确定"); } private void init() { sp = getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); + conUserIconTag = 1; DraweeController controller = Fresco.newDraweeControllerBuilder() .setUri("res:///" + R.drawable.scan_receiver) @@ -115,7 +125,7 @@ public class ChooseReceiverActivity extends BaseActivity implements View.OnClick mScanHint.setText(Html.fromHtml(""+"搜不到对方?"+"")); isStopScan = false; - isConnSuccess = false; + isDestroy = false; if (HotspotManager.isApOn(this)) { HotspotManager.disableAp(this); @@ -160,26 +170,38 @@ public class ChooseReceiverActivity extends BaseActivity implements View.OnClick for (int i = 0; i < mScanResultList.size(); i++) { ScanResult scanResult = mScanResultList.get(i); Utils.log(i + "=====" + scanResult.SSID ); + + int icon = 1; + try { + icon = Integer.parseInt(scanResult.SSID.substring(scanResult.SSID.length() - 1)); + } catch (Exception e) { + e.printStackTrace(); + } + switch (i) { case 0: choosereceiver_user1.setVisibility(View.VISIBLE); choosereceiver_user1_name.setText(scanResult.SSID); choosereceiver_user1.setOnClickListener(this); + userIcon1.setImageURI(UserIconUtils.getUserIcon(icon)); break; case 1: choosereceiver_user2.setVisibility(View.VISIBLE); choosereceiver_user2_name.setText(scanResult.SSID); choosereceiver_user2.setOnClickListener(this); + userIcon2.setImageURI(UserIconUtils.getUserIcon(icon)); break; case 2: choosereceiver_user3.setVisibility(View.VISIBLE); choosereceiver_user3_name.setText(scanResult.SSID); choosereceiver_user3.setOnClickListener(this); + userIcon3.setImageURI(UserIconUtils.getUserIcon(icon)); break; case 3: choosereceiver_user4.setVisibility(View.VISIBLE); choosereceiver_user4_name.setText(scanResult.SSID); choosereceiver_user4.setOnClickListener(this); + userIcon4.setImageURI(UserIconUtils.getUserIcon(icon)); break; } } @@ -231,6 +253,11 @@ public class ChooseReceiverActivity extends BaseActivity implements View.OnClick WifiMgr.getInstance(this).openWifi(); WifiMgr.getInstance(this).addNetwork(WifiMgr.createWifiCfg(ssid, null, WifiMgr.WIFICIPHER_NOPASS)); + try { + conUserIconTag = Integer.parseInt(ssid.substring(ssid.length() - 1)); + } catch (Exception e) { + e.printStackTrace(); + } createSendMsgToServerRunnable(WifiMgr.getInstance(this).getIpAddressFromHotspot()); } @@ -287,13 +314,14 @@ public class ChooseReceiverActivity extends BaseActivity implements View.OnClick JSONObject senderData = new JSONObject(); senderData.put(Constant.MSG_FILE_RECEIVER_INIT, sp.getString("user_name", "光环用户")); + senderData.put("UserIcon", sp.getInt("default_user_icon", 1)); sendData = senderData.toString().getBytes(BaseTransfer.UTF_8); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, ipAddressName, serverPort); mDatagramSocket.send(sendPacket); - while(true) { + while(!isDestroy) { DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); mDatagramSocket.receive(receivePacket); String response = new String(receivePacket.getData(), 0, receivePacket.getLength()).trim(); @@ -302,16 +330,18 @@ public class ChooseReceiverActivity extends BaseActivity implements View.OnClick if(response != null && response.contains(Constant.MSG_FILE_RECEIVER_INIT_SUCCESS)) { JSONObject jsonObject = new JSONObject(response); Utils.log("ChooseReceiverActivity:: 收到UDP请求::SUCCESS=" + jsonObject.getString(Constant.MSG_FILE_RECEIVER_INIT_SUCCESS)); - isConnSuccess = true; + Map userMap = new HashMap<>(); + userMap.put("receiverName", jsonObject.getString(Constant.MSG_FILE_RECEIVER_INIT_SUCCESS)); + userMap.put("usericon", String.valueOf(conUserIconTag)); + + AppController.put("userMap", userMap); // 进入文件发送列表界面 (并且通知文件接收方进入文件接收列表界面) Intent intent = new Intent(ChooseReceiverActivity.this, FileSenderActivity.class); - intent.putExtra("receiverName", jsonObject.getString(Constant.MSG_FILE_RECEIVER_INIT_SUCCESS)); startActivity(intent); closeSocket(); - Utils.log("==========发送销毁消息"); Intent resultIntent= new Intent(); - setResult(0*123, resultIntent); + setResult(0x123, resultIntent); finish(); break; } @@ -347,7 +377,11 @@ public class ChooseReceiverActivity extends BaseActivity implements View.OnClick closeSocket(); } - + @Override + protected void onDestroy() { + super.onDestroy(); + isDestroy = true; + } /** * 关闭UDP Socket 流 diff --git a/app/src/main/java/com/gh/gamecenter/CleanApkActivity.java b/app/src/main/java/com/gh/gamecenter/CleanApkActivity.java index 087ad54659..e079dee5fb 100644 --- a/app/src/main/java/com/gh/gamecenter/CleanApkActivity.java +++ b/app/src/main/java/com/gh/gamecenter/CleanApkActivity.java @@ -103,7 +103,7 @@ public class CleanApkActivity extends BaseActivity implements CleanApkAdapter.On for (int i = 0; i < apkList.size(); i++) { if (selectPosition.get(i) && apkList.get(i).getInstallStatus() == 1) { DialogUtils.showWarningDialog(CleanApkActivity.this, "删除安装包" - , "已选的安装包中可能包含未安装的应用,确定删除吗?", "取消 ", "确定" + , "已选的安装包中包含未安装的应用,确定删除吗?", "取消 ", "确定" , new DialogUtils.ConfiremListener() { @Override public void onConfirem() { @@ -184,7 +184,7 @@ public class CleanApkActivity extends BaseActivity implements CleanApkAdapter.On String sizeName = df.format(size) + "MB"; mApkCount.setText(Html.fromHtml("找到" + apkList.size() + "个安装包,占用" - + "" + sizeName + ""+ "空间")); + + "" + sizeName + ""+ "空间")); mScanPb.setVisibility(View.GONE); mApkSelectAll.setVisibility(View.VISIBLE); } diff --git a/app/src/main/java/com/gh/gamecenter/FileReceiverActivity.java b/app/src/main/java/com/gh/gamecenter/FileReceiverActivity.java index 8dfe60cc78..1ea0e858b5 100644 --- a/app/src/main/java/com/gh/gamecenter/FileReceiverActivity.java +++ b/app/src/main/java/com/gh/gamecenter/FileReceiverActivity.java @@ -17,12 +17,14 @@ import com.facebook.drawee.view.SimpleDraweeView; import com.gh.base.AppController; import com.gh.base.BaseActivity; import com.gh.common.util.DialogUtils; +import com.gh.common.util.UserIconUtils; import com.gh.common.util.Utils; import com.gh.download.DownloadDao; import com.gh.download.DownloadEntity; import com.gh.download.DownloadStatus; import com.gh.gamecenter.adapter.FileReceiverAdapter; import com.gh.gamecenter.eventbus.EBPackage; +import com.gh.gamecenter.kuaichuan.BaseTransfer; import com.gh.gamecenter.kuaichuan.Constant; import com.gh.gamecenter.kuaichuan.FileInfo; import com.gh.gamecenter.kuaichuan.FileReceiver; @@ -30,7 +32,11 @@ import com.gh.gamecenter.kuaichuan.HotspotManager; import com.gh.gamecenter.kuaichuan.IpPortInfo; import com.gh.gamecenter.kuaichuan.WifiMgr; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.IOException; +import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.ServerSocket; import java.net.Socket; @@ -63,8 +69,11 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd private FileReceiver mFileReceiver; + private DatagramSocket mDatagramSocket; + private boolean isReceivesOver; private boolean isOpenWifi; //记录开热点前的WiFi状态 + private boolean isDestroy; Handler handler = new Handler() { @Override @@ -81,6 +90,11 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd colsePage(); return; } + + if (index == -1) { + Utils.toast(FileReceiverActivity.this, " 获取刷新位置异常"); + return; + } FileInfo fileInfo = mFileInfos.get(index); if (msg.what == FileInfo.FLAG_DEFAULT) { // 传输中更新界面 long progress = (long) msg.obj; @@ -109,11 +123,15 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd if (mCurFileInfo == null) { return -100; } - if (fileInfo.getFilePath().equals(mCurFileInfo.getFilePath())) { + if (fileInfo.getFileTag().equals(mCurFileInfo.getFileTag())) { return i; } } - Utils.log("FileReceiverActivity:: 获取刷新位置异常"); + Utils.log("FileReceiverActivity:: 获取刷新位置异常" + mFileInfos.size()); + for (FileInfo mFileInfo : mFileInfos) { + Utils.log("FileReceiverActivity:: 位置异常mFileInfos====" + mFileInfo.getFileTag() + "==" + mFileInfo.getName()); + Utils.log("FileReceiverActivity:: 位置异常mCurFileInfo====" + mCurFileInfo.getFileTag() + "==" + mCurFileInfo.getName()); + } return -1; } @@ -124,6 +142,7 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd init(contentView, "接收游戏"); isReceivesOver = false; + isDestroy = false; mFileReceiverAdapter = new FileReceiverAdapter(this); mReceiverRv.setLayoutManager(new LinearLayoutManager(this)); @@ -156,7 +175,7 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd mSenderUserDes.setText(mFileInfos.size() + "个游戏,共" + sizeName); mSenderUserName.setText("来自-" + mIpPortInfo.getSenderName()); - mSenderUserIcon.setImageURI("res:///" + R.drawable.logo); + mSenderUserIcon.setImageURI(UserIconUtils.getUserIcon(mIpPortInfo.getSenderIcon())); } /** @@ -165,30 +184,91 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd private void initServer() { mReceiverServer = new ServerRunnable(Constant.DEFAULT_SERVER_PORT); new Thread(mReceiverServer).start(); + + new Thread(new Runnable() { + @Override + public void run() { + try { + receiverData(); + } catch (Exception e) { + Utils.log("FileReceiverActivity:: UDP请求异常" + e.toString() ); + e.printStackTrace(); + } + } + }).start(); + + } + + private void receiverData() throws Exception { + if (mDatagramSocket == null) { + mDatagramSocket = new DatagramSocket(Constant.DEFAULT_SERVER_SENDING_PORT); + mDatagramSocket.setBroadcast(true); + } + + byte[] receiveData = new byte[1024]; + + Utils.log("FileReceiverActivity:: 开始接收UDP请求::" + Constant.DEFAULT_SERVER_SENDING_PORT + "::" +mDatagramSocket.getInetAddress()); + while (!isDestroy) { + Utils.log("FileReceiverActivity:: 开始接收UDP请求" ); + DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); + mDatagramSocket.receive(receivePacket); + String response = new String(receivePacket.getData(), 0, receivePacket.getLength()).trim(); + Utils.log("FileReceiverActivity:: 接收UDP请求" + response); + if (response != null && response.equals(Constant.MSG_ADD_DATA_OVER)) { + handler.post(new Runnable() { + @Override + public void run() { + mFileReceiverAdapter.update(); + initUserData(); + } + }); + + sendMessageToSender(Constant.MSG_ADD_DATA_OVER); + Utils.log("FileReceiverActivity:: 回复信息" + Constant.MSG_ADD_DATA_OVER); + } else if (response != null) { + parseFileInfo(response); + } + + } + + } + + /** + * 解析FileInfo + * @param msg + */ + private void parseFileInfo(String msg) { + mFileInfos = (List) AppController.get("FileInfo", false); //TODO mFileInfos 数据异常 需要重新获取 + FileInfo fileInfo = FileInfo.toObject(msg); + if(fileInfo != null && fileInfo.getFilePath() != null){ + mFileInfos.add(fileInfo); + AppController.put("FileInfo", mFileInfos); + + } } - DatagramSocket mDatagramSocket; @Override public void OnCancelPosition(final int position) { - if (position == getCurrentFileInfoIndex()) { - mFileReceiver.cancel(); - } else { - Utils.toast(this, "在传送中的游戏才可以取消"); +// if (position == getCurrentFileInfoIndex()) { +// mFileReceiver.cancel(); +// } else { +// Utils.toast(this, "在传送中的游戏才可以取消"); +// } + + + //TODO 接收方发送取消消息 会导致接收列表时无法回复信息 == 将消息整合在一起 + Utils.log("接收方发送取消消息 让发送方取消"); + try { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("controlStatus", Constant.MSG_RECEIVER_CANCEL); + jsonObject.put("controlTag", position); + + sendMessageToSender(jsonObject.toString()); + } catch (Exception e) { + e.printStackTrace(); } -// Utils.log("接收方发送取消消息"); -// new Thread(new Runnable() { -// @Override -// public void run() { -// try { -// sendCancelControlToSender(position); -// } catch (Exception e) { -// Utils.log("接收方发送取消消息异常。。" + e.toString()); -// e.printStackTrace(); -// } -// } -// }).start(); } //安装事件 @@ -206,22 +286,23 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd } } -// private void sendCancelControlToSender(int position) throws Exception { -// if (mDatagramSocket == null) { -// mDatagramSocket = new DatagramSocket(Constant.DEFAULT_SERVER_CANCEL_PORT); -// } -// -// byte[] sendData = null; -// -// JSONObject jsonObject = new JSONObject(); -// jsonObject.put("controlStatus", Constant.MSG_RECEIVER_CANCEL); -// jsonObject.put("controlTag", position); -// sendData = jsonObject.toString().getBytes(BaseTransfer.UTF_8); -// DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, mIpPortInfo.getInetAddress(), Constant.DEFAULT_SERVER_CANCEL_PORT); -// mDatagramSocket.send(sendPacket); -// -// Utils.log("接收方取消接收操作已发送至接收方:" + jsonObject + "==" + mIpPortInfo.getInetAddress() + "==" + Constant.DEFAULT_SERVER_CANCEL_PORT); -// } + private void sendMessageToSender(final String sendData) throws Exception { + new Thread(new Runnable() { + @Override + public void run() { + try { + byte[] bytes = sendData.getBytes(BaseTransfer.UTF_8); + DatagramPacket sendPacket = new DatagramPacket(bytes, bytes.length, mIpPortInfo.getInetAddress(), Constant.DEFAULT_SERVER_SENDING_PORT); + mDatagramSocket.send(sendPacket); + + Utils.log("接收方消息已发送至接收方:" + sendData + "==" + mIpPortInfo.getInetAddress() + "==" + Constant.DEFAULT_SERVER_SENDING_PORT); + } catch (Exception e) { + Utils.log("接收方发送消息异常。。" + e.toString()); + e.printStackTrace(); + } + } + }).start(); + } /** * ServerSocket启动线程 @@ -342,17 +423,31 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd backHint(); } + @Override + protected void onDestroy() { + super.onDestroy(); + isDestroy = true; + } + @OnClick(R.id.actionbar_rl_back) public void back() { backHint(); } private void colsePage() { + + if(mDatagramSocket != null) { + mDatagramSocket.disconnect(); + mDatagramSocket.close(); + mDatagramSocket = null; + } + //关闭热点 HotspotManager.disableAp(this); mReceiverServer.close(); - AppController.get("FileInfo", true); + AppController.remove("FileInfo"); + mFileInfos.clear(); HotspotManager.disableAp(FileReceiverActivity.this); if (isOpenWifi) { @@ -360,7 +455,6 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd } for (FileInfo fileInfo : mFileInfos) { - // TODO 接收完成未安装的游戏,添加到下载管理-游戏下载 if (fileInfo.getResult() == FileInfo.FLAG_SUCCESS) { DownloadEntity entry = new DownloadEntity(); entry.setName(fileInfo.getName()); @@ -370,6 +464,13 @@ public class FileReceiverActivity extends BaseActivity implements FileReceiverAd entry.setPercent(100.0); entry.setUrl(fileInfo.getFilePath()); //url拿 路径替代 entry.setStatus(DownloadStatus.done); + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("KuaiChuanIcon", Environment.getExternalStorageDirectory() + "/GH-KC/" + fileInfo.getName() + ".apk"); + } catch (JSONException e) { + e.printStackTrace(); + } + entry.setIcon(jsonObject.toString()); DownloadDao.getInstance(this).newOrUpdate(entry); } } diff --git a/app/src/main/java/com/gh/gamecenter/FileSenderActivity.java b/app/src/main/java/com/gh/gamecenter/FileSenderActivity.java index e1d1c1c69b..0a958d139d 100644 --- a/app/src/main/java/com/gh/gamecenter/FileSenderActivity.java +++ b/app/src/main/java/com/gh/gamecenter/FileSenderActivity.java @@ -1,6 +1,7 @@ package com.gh.gamecenter; import android.Manifest; +import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; @@ -10,12 +11,15 @@ import android.support.v4.content.ContextCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.TextView; import com.facebook.drawee.view.SimpleDraweeView; import com.gh.base.AppController; import com.gh.base.BaseActivity; import com.gh.common.util.DialogUtils; +import com.gh.common.util.UserIconUtils; import com.gh.common.util.Utils; import com.gh.gamecenter.adapter.FileSenderAdapter; import com.gh.gamecenter.kuaichuan.Constant; @@ -23,10 +27,16 @@ import com.gh.gamecenter.kuaichuan.FileInfo; import com.gh.gamecenter.kuaichuan.FileSender; import com.gh.gamecenter.kuaichuan.WifiMgr; +import org.json.JSONObject; + +import java.net.DatagramPacket; import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InetSocketAddress; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; +import java.util.Map; import butterknife.BindView; import butterknife.OnClick; @@ -41,20 +51,25 @@ public class FileSenderActivity extends BaseActivity implements FileSenderAdapte @BindView(R.id.sender_user_name) TextView mSenderUserName; @BindView(R.id.sender_user_send_des) TextView mSenderUserDes; @BindView(R.id.sender_hint) TextView mSenderHint; + @BindView(R.id.sender_keep_send) RelativeLayout mKeepSend; + @BindView(R.id.sender_bottom) LinearLayout mSenderBottom; private FileSenderAdapter mSenderAdapter; + private DatagramSocket mDatagramSocket; + private List mFileInfos; private List mFileSenderList = new ArrayList<>(); private boolean isSendOver; + private boolean isDestroy; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); - if (msg.what == FileInfo.FLAG_DEFAULT){ + if (msg.what == FileInfo.FLAG_DEFAULT) { int position = (int) msg.obj; mFileInfos.get(position).setResult(FileInfo.FLAG_DEFAULT); mSenderAdapter.notifyItemChanged(position); @@ -84,39 +99,139 @@ public class FileSenderActivity extends BaseActivity implements FileSenderAdapte View contentView = View.inflate(this, R.layout.activity_file_sender, null); init(contentView, "发送游戏"); - isSendOver = false; + mFileInfos = (List) AppController.get("FileInfo", false); - mFileSenderList = new ArrayList<>();; - mSenderAdapter = new FileSenderAdapter(this); + isSendOver = false; + isDestroy = false; + + mFileSenderList = new ArrayList<>(); + mSenderAdapter = new FileSenderAdapter(this, mFileInfos); mSenderRv.setLayoutManager(new LinearLayoutManager(this)); mSenderRv.setAdapter(mSenderAdapter); init(); } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 0x178) { + mFileInfos = (List) AppController.get("FileInfo", false); + mSenderAdapter.notifyDataSetChanged(); + initUserData(); + Utils.log("FileSenderActivity:: onActivityResult::" + mFileInfos.size()); + new Thread(new Runnable() { + @Override + public void run() { + try { + sendFileInfo(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }).start(); + } + } + + private void sendFileInfo() throws Exception { + if (mDatagramSocket == null) { + mDatagramSocket = new DatagramSocket(null); + mDatagramSocket.setReuseAddress(true); + mDatagramSocket.bind(new InetSocketAddress(Constant.DEFAULT_SERVER_SENDING_PORT)); + } + String ipAddress = WifiMgr.getInstance(this).getIpAddressFromHotspot(); + InetAddress ipAddressName = InetAddress.getByName(ipAddress); // 转译 + //发送apk列表 + for (FileInfo fileInfo : mFileInfos) { + if (fileInfo.getResult() == 0) { // 过滤已发送过的列表 + String fileInfoJson = FileInfo.toJsonStr(fileInfo); + Utils.log("FileSenderActivity:: 发送的文件列表::" + fileInfoJson ); + DatagramPacket sendFileInfoListPacket = new DatagramPacket(fileInfoJson.getBytes() + , fileInfoJson.getBytes().length, ipAddressName, Constant.DEFAULT_SERVER_SENDING_PORT); + mDatagramSocket.send(sendFileInfoListPacket); + Utils.log("FileSenderActivity:: 发送的文件列表完成::" + ipAddressName + "==" + Constant.DEFAULT_SERVER_SENDING_PORT); + } + } + + DatagramPacket sendFileInfoListPacket = new DatagramPacket(Constant.MSG_ADD_DATA_OVER.getBytes() + , Constant.MSG_ADD_DATA_OVER.getBytes().length, ipAddressName, Constant.DEFAULT_SERVER_SENDING_PORT); + mDatagramSocket.send(sendFileInfoListPacket); + Utils.log("FileSenderActivity:: 发送结束请求完成"); + } + + private void init() { Utils.log("FileSenderActivity == init()"); - mFileInfos = (List) AppController.get("FileInfo", false); initUserData(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constant.REQUEST_CODE_WRITE_FILE); - }else{ + } else{ Utils.log("FileSenderActivity == initSendServer()" + mFileInfos.size()); try { initSendServer();//开启传送文件 + startReceiver(); } catch (Exception e) { e.printStackTrace(); } } } + private void startReceiver() { + new Thread(new Runnable() { + @Override + public void run() { + try { + initTestReceiverData(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }).start(); + } + + private void initTestReceiverData() throws Exception { + if (mDatagramSocket == null) { + mDatagramSocket = new DatagramSocket(null); + mDatagramSocket.setReuseAddress(true); + mDatagramSocket.bind(new InetSocketAddress(Constant.DEFAULT_SERVER_SENDING_PORT)); + } + Utils.log("接收方取消Socket端口" + Constant.DEFAULT_SERVER_SENDING_PORT); + byte[] receiveData = new byte[1024]; + // 主要接收 接收方取消操作 + while (!isDestroy) { + DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); + mDatagramSocket.receive(receivePacket); + String response = new String( receivePacket.getData(),0 , receivePacket.getLength()).trim(); + Utils.log("====接收取消消息中。。。" + response); + if(response != null && response.contains(Constant.MSG_RECEIVER_CANCEL)){ + Utils.log("====接收取消消息完毕。。。" + response); + + // 进入文件发送列表界面 (并且通知文件接收方进入文件接收列表界面) + JSONObject jsonObject = new JSONObject(response); + int cancelPosition = (int) jsonObject.get("controlTag"); + FileSender fileSender = mFileSenderList.get(cancelPosition); + if (fileSender != null && fileSender.isRunning()) { + Utils.log("接收方取消发送"); + fileSender.cancel(); + } + } else if (response != null && response.contains(Constant.MSG_ADD_DATA_OVER)) { + try { + Utils.log("====收到UDP结束请求 开始传送文件"); + initSendServer();//开启传送文件 + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + //初始化用户数据 private void initUserData() { - String receiverName = getIntent().getExtras().getString("receiverName"); + Map map = (Map) AppController.get("userMap", false); long allGameSize = 0; for (FileInfo mFileInfo : mFileInfos) { @@ -128,59 +243,68 @@ public class FileSenderActivity extends BaseActivity implements FileSenderAdapte String sizeName = df.format(size) + "MB"; mSenderUserDes.setText(mFileInfos.size() + "个游戏,共" + sizeName); - mSenderUserName.setText("发给-" + receiverName); - mSenderUserIcon.setImageURI("res:///" + R.drawable.logo); + mSenderUserName.setText("发给-" + map.get("receiverName")); + mSenderUserIcon.setImageURI(UserIconUtils.getUserIcon(Integer.parseInt(map.get("usericon")))); + + mSenderBottom.setVisibility(View.GONE); } - DatagramSocket mDatagramSocket; private void initSendServer() throws Exception { String serverIp = WifiMgr.getInstance(this).getIpAddressFromHotspot(); - for (int i = 0; i < mFileInfos.size(); i++) { - final FileInfo mFileInfo = mFileInfos.get(i); - Utils.log("FileSenderActivity == initSendServer()===" + mFileInfo.getName()); - FileSender fileSender = new FileSender(this, mFileInfo, serverIp, Constant.DEFAULT_SERVER_PORT); - final int finalI = i; + + Utils.log("====FileSenderActivity传送个数::" + mFileInfos.size()); + + + // TODO: 发送的首个游戏 socket被拒绝的概率较大 延迟0.5秒发送试试 + Thread.sleep(500); //test + + for (final FileInfo fileInfo : mFileInfos) { + Utils.log("FileSenderActivity == initSendServer()===" + fileInfo.getName() + "==" + fileInfo.getResult()); + + if (fileInfo.getResult() != 0) continue; // result != 0 是已经传送过的apk + + FileSender fileSender = new FileSender(this, fileInfo, serverIp, Constant.DEFAULT_SERVER_PORT); fileSender.setOnSendListener(new FileSender.OnSendListener() { @Override public void onStart() { - Utils.log("快传文件发送::onStart" + "==" + mFileInfo.getName()); + Utils.log("快传文件发送::onStart" + "==" + fileInfo.getName()); } @Override public void onProgress(long progress, long total) { - Utils.log("快传文件发送中..." + progress + "==" + total + "==" + mFileInfo.getName()); - mFileInfo.setProgress(progress); + Utils.log("快传文件发送中..." + progress + "==" + total + "==" + fileInfo.getName()); + fileInfo.setProgress(progress); Message message = new Message(); message.what = FileInfo.FLAG_DEFAULT; - message.obj = finalI; + message.obj = getCurrentFileInfoIndex(fileInfo); handler.sendMessage(message); } @Override public void onSuccess(FileInfo fileInfo) { - Utils.log("快传文件发送成功::onSuccess" + "==" + mFileInfo.getName()); + Utils.log("快传文件发送成功::onSuccess" + "==" + fileInfo.getName()); Message message = new Message(); message.what = FileInfo.FLAG_SUCCESS; - message.obj = finalI; + message.obj = getCurrentFileInfoIndex(fileInfo); handler.sendMessage(message); } @Override public void onFailure(Throwable t, FileInfo fileInfo) { - Utils.log("快传文件发送失败::onFailure" + "==" + mFileInfo.getName()); + Utils.log("快传文件发送失败::onFailure" + "==" + fileInfo.getName()); Message message = new Message(); message.what = FileInfo.FLAG_FAILURE; - message.obj = finalI; + message.obj = getCurrentFileInfoIndex(fileInfo); handler.sendMessage(message); } @Override public void onCancel(FileInfo fileInfo) { - Utils.log("快传文件用户主动取消::onCancel" + "==" + mFileInfo.getName()); + Utils.log("快传文件用户主动取消::onCancel" + "==" + fileInfo.getName()); Message message = new Message(); message.what = FileInfo.FLAG_CANCEL; - message.obj = finalI; + message.obj = getCurrentFileInfoIndex(fileInfo); handler.sendMessage(message); } @@ -188,33 +312,26 @@ public class FileSenderActivity extends BaseActivity implements FileSenderAdapte mFileSenderList.add(fileSender); AppController.FILE_SENDER_EXECUTOR.execute(fileSender); } + } -// mDatagramSocket = new DatagramSocket(Constant.DEFAULT_SERVER_CANCEL_PORT); -// Utils.log("接收方取消Socket端口" + Constant.DEFAULT_SERVER_CANCEL_PORT); -// byte[] receiveData = new byte[1024]; -// byte[] sendData = null; -// // 主要接收 接收方取消操作 -// while (true) { -// DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); -// mDatagramSocket.receive(receivePacket); -// String response = new String( receivePacket.getData(), BaseTransfer.UTF_8).trim(); -// Utils.log("接收取消消息中。。。" + response); -// if(response != null && response.contains(Constant.MSG_RECEIVER_CANCEL)){ -// Utils.log("接收取消消息完毕。。。" + response); -// -// // 进入文件发送列表界面 (并且通知文件接收方进入文件接收列表界面) -// JSONObject jsonObject = new JSONObject(response); -// int cancelPosition = (int) jsonObject.get("controlTag"); -// FileSender fileSender = mFileSenderList.get(cancelPosition); -// if (fileSender != null && fileSender.isRunning()) { -// Utils.log("接收方取消发送"); -// fileSender.cancel(); -// } -// } -// } + private int getCurrentFileInfoIndex(FileInfo curFileInfo) { + for (int i = 0; i < mFileInfos.size(); i++) { + FileInfo fileInfo = mFileInfos.get(i); + if (curFileInfo == null) { + return -100; + } + if (fileInfo.getFileTag().equals(curFileInfo.getFileTag())) { + Utils.log("FileSenderActivity === index::" + i); + return i; + } + } + Utils.log("FileReceiverActivity:: 获取刷新位置异常"); + return -1; } private void initSenderHint(){ + mSenderBottom.setVisibility(View.VISIBLE); + int sendSuccess = 0; isSendOver = true; for (FileInfo mFileInfo : mFileInfos) { @@ -253,9 +370,21 @@ public class FileSenderActivity extends BaseActivity implements FileSenderAdapte backHint(); } - @OnClick(R.id.actionbar_rl_back) - public void back() { - backHint(); + @Override + protected void onDestroy() { + super.onDestroy(); + isDestroy = true; + } + + @OnClick({R.id.actionbar_rl_back, R.id.sender_keep_send}) + public void onClick(View view) { + if (view.getId() == R.id.actionbar_rl_back) { + backHint(); + } else if (view.getId() == R.id.sender_keep_send) { + Intent intent = new Intent(this, KcSelectGameActivity.class); + intent.putExtra("isConn", true); + startActivityForResult(intent, 0x178); + } } @@ -266,10 +395,23 @@ public class FileSenderActivity extends BaseActivity implements FileSenderAdapte for(FileSender fileSender : mFileSenderList){ if(fileSender != null){ fileSender.cancel(); + fileSender.finish(); } } } + public void colsePage() { + if(mDatagramSocket != null) { + mDatagramSocket.disconnect(); + mDatagramSocket.close(); + mDatagramSocket = null; + } + + stopAllFileSendingTask(); + AppController.remove("FileInfo"); + FileSenderActivity.this.finish(); + } + private void backHint() { if(!isSendOver){ DialogUtils.showWarningDialog(FileSenderActivity.this, "退出传送", "退出会中断所有游戏的传送,确定要退出吗?" @@ -277,15 +419,12 @@ public class FileSenderActivity extends BaseActivity implements FileSenderAdapte , new DialogUtils.ConfiremListener() { @Override public void onConfirem() { - stopAllFileSendingTask(); - AppController.get("FileInfo", true); - FileSenderActivity.this.finish(); + colsePage(); + } }, null); } else { - stopAllFileSendingTask(); - AppController.get("FileInfo", true); - FileSenderActivity.this.finish(); + colsePage(); } diff --git a/app/src/main/java/com/gh/gamecenter/KcSelectGameActivity.java b/app/src/main/java/com/gh/gamecenter/KcSelectGameActivity.java index a22d1d7387..c7e31b3120 100644 --- a/app/src/main/java/com/gh/gamecenter/KcSelectGameActivity.java +++ b/app/src/main/java/com/gh/gamecenter/KcSelectGameActivity.java @@ -33,10 +33,12 @@ public class KcSelectGameActivity extends BaseActivity { private KcSelectGameAdapter mAdapter; + private boolean mIsConn; + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == 0*123) { + if (requestCode == 0x123) { finish(); } } @@ -47,6 +49,13 @@ public class KcSelectGameActivity extends BaseActivity { View contentView = View.inflate(this, R.layout.activity_kc_select_game, null); init(contentView, "选择游戏"); + if (getIntent() != null && getIntent().getExtras() != null) { + mIsConn = getIntent().getExtras().getBoolean("isConn"); + } else { + mIsConn = false; + } + + mAdapter = new KcSelectGameAdapter(this, mSelectSend); mSelectRv.setLayoutManager(new LinearLayoutManager(this)); @@ -60,9 +69,22 @@ public class KcSelectGameActivity extends BaseActivity { Utils.toast(KcSelectGameActivity.this, "请选择游戏"); return; } - AppController.put("FileInfo", selectData); - Intent intent = new Intent(KcSelectGameActivity.this, ChooseReceiverActivity.class); - startActivityForResult(intent, 0*123); + + if (mIsConn) { + List oldInfo = (List) AppController.get("FileInfo", false); + for (FileInfo fileInfo : selectData) { + oldInfo.add(fileInfo); + } + + AppController.put("FileInfo", oldInfo); + setResult(0x178); + finish(); + } else { + AppController.put("FileInfo", selectData); + Intent intent = new Intent(KcSelectGameActivity.this, ChooseReceiverActivity.class); + startActivityForResult(intent, 0x123); + } + } }); diff --git a/app/src/main/java/com/gh/gamecenter/ReceiverWaitingActivity.java b/app/src/main/java/com/gh/gamecenter/ReceiverWaitingActivity.java index b9990c43f9..10404ca6fb 100644 --- a/app/src/main/java/com/gh/gamecenter/ReceiverWaitingActivity.java +++ b/app/src/main/java/com/gh/gamecenter/ReceiverWaitingActivity.java @@ -19,6 +19,7 @@ import com.gh.base.AppController; import com.gh.base.BaseActivity; import com.gh.common.constant.Config; import com.gh.common.util.RandomUtils; +import com.gh.common.util.UserIconUtils; import com.gh.common.util.Utils; import com.gh.gamecenter.kuaichuan.BaseTransfer; import com.gh.gamecenter.kuaichuan.Constant; @@ -34,6 +35,7 @@ import org.json.JSONObject; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; @@ -62,6 +64,7 @@ public class ReceiverWaitingActivity extends BaseActivity { private boolean mIsInitialized; private boolean isOpenWifi; //记录开热点前的WiFi状态 + private boolean isDestroy; private String mySsid; @@ -103,9 +106,11 @@ public class ReceiverWaitingActivity extends BaseActivity { sp = getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); mIsInitialized = false; + isDestroy = false; isOpenWifi = WifiMgr.getInstance(this).isWifiEnable(); mUserName.setText(sp.getString("user_name", "光环用户")); + mUserIcon.setImageURI(UserIconUtils.getUserIcon(sp.getInt("default_user_icon", 1))); if (isOpenWifi) { WifiMgr.getInstance(this).closeWifi(); @@ -152,7 +157,7 @@ public class ReceiverWaitingActivity extends BaseActivity { for (int i : randomArray) { mySsid = mySsid + chars.charAt(i); } - mySsid = mySsid + 1; + mySsid = mySsid + sp.getInt("default_user_icon", 1); HotspotManager.configApState(this, mySsid); // change Ap state :boolean } @@ -166,6 +171,7 @@ public class ReceiverWaitingActivity extends BaseActivity { try { startFileReceiverServer(Constant.DEFAULT_SERVER_COM_PORT); } catch (Exception e) { + Utils.log("发送UDP消息到 文件发送方 异常" + e.toString()); e.printStackTrace(); } } @@ -191,12 +197,16 @@ public class ReceiverWaitingActivity extends BaseActivity { count ++; } - mDatagramSocket = new DatagramSocket(serverPort); + if (mDatagramSocket == null) { + mDatagramSocket = new DatagramSocket(null); + mDatagramSocket.setReuseAddress(true); + mDatagramSocket.bind(new InetSocketAddress(serverPort)); + } byte[] receiveData = new byte[1024]; byte[] sendData; Utils.log("接收接受信息 "); - while (true) { + while (!isDestroy) { //接收 文件发送方的消息 DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); mDatagramSocket.receive(receivePacket); @@ -205,15 +215,11 @@ public class ReceiverWaitingActivity extends BaseActivity { int port = receivePacket.getPort(); Utils.log("接收信息中。。。" + msg ); - if(msg != null && msg.contains(Constant.MSG_FILE_RECEIVER_INIT)){ + if(msg != null && msg.contains(Constant.MSG_FILE_RECEIVER_INIT)) { Utils.log("接收方初始化完毕准备进去传输页面 并回馈消息给发送者" + inetAddress); AppController.put("FileInfo", mFileInfos); //保存数据列表 - for (FileInfo mFileInfo : mFileInfos) { - Utils.log("=======zz===" + mFileInfo.getSize() + "==" + mFileInfo.getName() + "==" + mFileInfo.getFilePath()); - } - // 反馈 文件发送方的消息 // sendData = Constant.MSG_FILE_RECEIVER_INIT_SUCCESS.getBytes(BaseTransfer.UTF_8); JSONObject receiverData = new JSONObject(); @@ -225,7 +231,8 @@ public class ReceiverWaitingActivity extends BaseActivity { Message message = new Message(); message.what = 0; - message.obj = new IpPortInfo(inetAddress, port, new JSONObject(msg).getString(Constant.MSG_FILE_RECEIVER_INIT)); + JSONObject jsonObject = new JSONObject(msg); + message.obj = new IpPortInfo(inetAddress, port, jsonObject.getString(Constant.MSG_FILE_RECEIVER_INIT), jsonObject.getInt("UserIcon")); mHandler.sendMessage(message); } else { @@ -243,7 +250,6 @@ public class ReceiverWaitingActivity extends BaseActivity { */ private void parseFileInfo(String msg) { FileInfo fileInfo = FileInfo.toObject(msg); - Utils.log("parseFileInfo" + fileInfo.getFilePath() + "==" + fileInfo.getName() + "==" + fileInfo.getSize()); if(fileInfo != null && fileInfo.getFilePath() != null){ mFileInfos.add(fileInfo); } @@ -300,8 +306,13 @@ public class ReceiverWaitingActivity extends BaseActivity { } closeSocket(); + finish(); + } - this.finish(); + @Override + protected void onDestroy() { + super.onDestroy(); + isDestroy = true; } diff --git a/app/src/main/java/com/gh/gamecenter/SelectUserIconActivity.java b/app/src/main/java/com/gh/gamecenter/SelectUserIconActivity.java new file mode 100644 index 0000000000..14a6abd41c --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/SelectUserIconActivity.java @@ -0,0 +1,118 @@ +package com.gh.gamecenter; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.provider.MediaStore; +import android.view.View; +import android.widget.TextView; + +import com.gh.base.BaseActivity; +import com.gh.common.constant.Config; +import com.gh.common.util.UserIconUtils; +import com.gh.common.util.Utils; + +import butterknife.BindView; +import butterknife.OnClick; + +/** + * Created by khy on 2017/2/10. + */ +public class SelectUserIconActivity extends BaseActivity { + + @BindView(R.id.skip_media_store) TextView mSkipMediaStore; + + private SharedPreferences sp; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + View contentView = View.inflate(this, R.layout.activity_select_user_icon, null); + init(contentView, "选择头像"); + + sp = getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); + + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (data != null && requestCode == 0x123) { + Uri selectedImage = data.getData(); + if (selectedImage == null) { + return; + } + String[] filePathColumn = { MediaStore.Images.Media.DATA }; + + Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); + if (cursor == null) { + return; + } + cursor.moveToFirst(); + + int columnIndex = cursor.getColumnIndex(filePathColumn[0]); + String picturePath = cursor.getString(columnIndex); + cursor.close(); + + Utils.log("picturePath = " + picturePath); + // 上传头像 + Intent intent = new Intent(this, CropImageActivity.class); + intent.putExtra("path", picturePath); + intent.putExtra("entrance", "(我的光环)"); + startActivityForResult(intent, 0x124); + } else if (data != null && requestCode == 0x124) { + String url = data.getExtras().getString("url"); + Intent intent = new Intent(); + intent.putExtra("url", url); + setResult(0x125, intent); + finish(); + } + } + + @OnClick({R.id.user_default_icon_1, R.id.user_default_icon_2, R.id.user_default_icon_3 ,R.id.user_default_icon_4, + R.id.user_default_icon_5, R.id.user_default_icon_6, R.id.user_default_icon_7, R.id.user_default_icon_8, R.id.skip_media_store}) + public void onClick(View view){ + switch (view.getId()) { + case R.id.user_default_icon_1: + postUserIocn(1); + break; + case R.id.user_default_icon_2: + postUserIocn(2); + break; + case R.id.user_default_icon_3: + postUserIocn(3); + break; + case R.id.user_default_icon_4: + postUserIocn(4); + break; + case R.id.user_default_icon_5: + postUserIocn(5); + break; + case R.id.user_default_icon_6: + postUserIocn(6); + break; + case R.id.user_default_icon_7: + postUserIocn(7); + break; + case R.id.user_default_icon_8: + postUserIocn(8); + break; + case R.id.skip_media_store: + Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + startActivityForResult(intent, 0x123); + break; + } + } + + public void postUserIocn(int i) { + sp.edit().putInt("default_user_icon", i).apply(); + Intent intent = new Intent(); + intent.putExtra("url", UserIconUtils.getUserIcon(i)); + setResult(0x125, intent); + finish(); + } + +} diff --git a/app/src/main/java/com/gh/gamecenter/ShareGhActivity.java b/app/src/main/java/com/gh/gamecenter/ShareGhActivity.java index 1e924452da..6a06bad6ad 100644 --- a/app/src/main/java/com/gh/gamecenter/ShareGhActivity.java +++ b/app/src/main/java/com/gh/gamecenter/ShareGhActivity.java @@ -10,6 +10,7 @@ import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.TextView; import com.gh.base.BaseActivity; @@ -30,6 +31,7 @@ public class ShareGhActivity extends BaseActivity { @BindView(R.id.gh_address_tv) TextView mGhAddress; @BindView(R.id.wifi_share_btn) Button mWifiShareBtn; @BindView(R.id.content_ll) LinearLayout mContentLl; + @BindView(R.id.share_rl) RelativeLayout mShareRl; @Override protected void onCreate(Bundle savedInstanceState) { @@ -40,7 +42,7 @@ public class ShareGhActivity extends BaseActivity { mGhAddress.setText(Html.fromHtml(""+"www.ghzhushou.com"+"")); createQrCode(); - ShareUtils.getInstance(this).showShareWindows(mContentLl, "http://www.ghzhushou.com?source=appshare300", "光环助手" + ShareUtils.getInstance(this).showShareWindows(mShareRl, "http://www.ghzhushou.com?source=appshare300", "光环助手" , "http://image.ghzhushou.com/pic/57d604808ab49e467d8b4568.png", null, false, false); } @@ -64,7 +66,7 @@ public class ShareGhActivity extends BaseActivity { @Override public void run() { final String filePath = getExternalCacheDir().getPath() + "/ShareImg/ShareQRCode.jpg"; - boolean success = QRCodeUtils.createQRImage("www.ghzhushou.com" + boolean success = QRCodeUtils.createQRImage("http://www.ghzhushou.com?source=appshare100" , 200, 200, filePath, ShareGhActivity.this); if (success) { runOnUiThread(new Runnable() { diff --git a/app/src/main/java/com/gh/gamecenter/ShareGhWfifActivity.java b/app/src/main/java/com/gh/gamecenter/ShareGhWfifActivity.java index 74c30bfebe..e5e5d166ba 100644 --- a/app/src/main/java/com/gh/gamecenter/ShareGhWfifActivity.java +++ b/app/src/main/java/com/gh/gamecenter/ShareGhWfifActivity.java @@ -1,12 +1,15 @@ package com.gh.gamecenter; +import android.content.Context; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.os.Bundle; import android.view.View; import android.widget.TextView; import com.gh.base.AppController; import com.gh.base.BaseActivity; +import com.gh.common.constant.Config; import com.gh.common.util.DialogUtils; import com.gh.common.util.RandomUtils; import com.gh.common.util.Utils; @@ -48,6 +51,8 @@ public class ShareGhWfifActivity extends BaseActivity { private List mUriHandlers; + private SharedPreferences sp; + private boolean isColseActivity; private boolean isOpenWifi; //记录开热点前的WiFi状态 @@ -66,6 +71,7 @@ public class ShareGhWfifActivity extends BaseActivity { mUriHandlers.add(new ImageUriHandler(this)); mUriHandlers.add(new DownloadUriHandler(this)); + sp = getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); isColseActivity = false; if (WifiMgr.getInstance(this).isWifiEnable()) { @@ -98,12 +104,13 @@ public class ShareGhWfifActivity extends BaseActivity { HotspotManager.isApOn(this); - mySsid = "GHZS-"; - int[] randomArray = RandomUtils.getRandomArray(4, 10); + String chars = "abcdefghijklmnopqrstuvwxyz"; + int[] randomArray = RandomUtils.getRandomArray(2, 25); + mySsid = "ghZS-"; for (int i : randomArray) { - mySsid = mySsid + i; + mySsid = mySsid + chars.charAt(i); } - + mySsid = mySsid + sp.getInt("default_user_icon", 1); HotspotManager.configApState(this, mySsid); // change Ap state :boolean } @@ -213,7 +220,7 @@ public class ShareGhWfifActivity extends BaseActivity { } private void backActivity() { - DialogUtils.showWarningDialog(this, "退出传送", "退出会中断所有游戏的传送,确定要退出吗?" + DialogUtils.showWarningDialog(this, "退出分享", "退出本页面即会关闭分享热点,确定退出吗?" , "取消", "确定" , new DialogUtils.ConfiremListener() { @Override diff --git a/app/src/main/java/com/gh/gamecenter/adapter/CleanApkAdapter.java b/app/src/main/java/com/gh/gamecenter/adapter/CleanApkAdapter.java index a367dab9da..fce956c141 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/CleanApkAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/CleanApkAdapter.java @@ -216,6 +216,7 @@ public class CleanApkAdapter extends RecyclerView.Adapter fileInfos) { this.mContext = activity; this.cancelListener = activity; - mFileInfos = (List) AppController.get("FileInfo", false); + this.mFileInfos = fileInfos; lastProgress = 0; } @@ -51,6 +51,7 @@ public class FileSenderAdapter extends RecyclerView.Adapter getSelectData() { List fileInfos = new ArrayList<>(); - + long l = System.currentTimeMillis(); for (int i = 0; i < selectPosition.keySet().size(); i++) { if (selectPosition.get(i)) { InstallGameEntity installGameEntity = gameList.get(i); @@ -221,7 +221,7 @@ public class KcSelectGameAdapter extends RecyclerView.Adapter"+"安装包清理"+"")); + cleanApk.setText(Html.fromHtml("手机空间不足?试试 " +""+"安装包清理"+"")); cleanApk.setOnClickListener(new View.OnClickListener() { @Override diff --git a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java index c975f6a525..5e5d6a706c 100644 --- a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java @@ -1,6 +1,9 @@ package com.gh.gamecenter.download; import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.graphics.Bitmap; import android.os.Message; import android.support.v4.util.ArrayMap; import android.support.v7.widget.RecyclerView; @@ -13,6 +16,7 @@ import android.widget.TextView; import android.widget.Toast; import com.gh.common.constant.Constants; +import com.gh.common.util.BitmapUtils; import com.gh.common.util.DataUtils; import com.gh.common.util.DialogUtils; import com.gh.common.util.DisplayUtils; @@ -32,6 +36,9 @@ import com.gh.gamecenter.adapter.viewholder.GameDownloadViewHolder; import com.gh.gamecenter.eventbus.EBDownloadChanged; import com.gh.gamecenter.manager.PackageManager; +import org.json.JSONException; +import org.json.JSONObject; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -154,7 +161,25 @@ class GameDownloadFragmentAdapter extends RecyclerView.Adapter fileInfoList){ - JSONArray jsonArray = new JSONArray(); - if(fileInfoList != null){ - for(FileInfo fileInfo : fileInfoList ){ - if(fileInfo != null){ - try { - jsonArray.put(new JSONObject(toJsonStr(fileInfo))); - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - } - return jsonArray.toString(); - } - } diff --git a/app/src/main/java/com/gh/gamecenter/kuaichuan/FileReceiver.java b/app/src/main/java/com/gh/gamecenter/kuaichuan/FileReceiver.java index 06c5cb1ced..7babad729b 100644 --- a/app/src/main/java/com/gh/gamecenter/kuaichuan/FileReceiver.java +++ b/app/src/main/java/com/gh/gamecenter/kuaichuan/FileReceiver.java @@ -145,6 +145,8 @@ public class FileReceiver extends BaseTransfer implements Runnable { //解析header String jsonStr = new String(headerBytes, UTF_8); + Utils.log("===接收到的json列表数据::" + jsonStr); + String[] strArray = jsonStr.split(SPERATOR); jsonStr = strArray[1].trim(); mFileInfo = FileInfo.toObject(jsonStr); diff --git a/app/src/main/java/com/gh/gamecenter/kuaichuan/FileSender.java b/app/src/main/java/com/gh/gamecenter/kuaichuan/FileSender.java index 7ed96d8047..ba5f212a1f 100644 --- a/app/src/main/java/com/gh/gamecenter/kuaichuan/FileSender.java +++ b/app/src/main/java/com/gh/gamecenter/kuaichuan/FileSender.java @@ -118,9 +118,10 @@ public class FileSender extends BaseTransfer implements Runnable { @Override public void init() throws Exception { - this.mSocket = new Socket(mServerIpAddress, mPort); - OutputStream os = this.mSocket.getOutputStream(); - mOutputStream = new BufferedOutputStream(os); + Utils.log("=== init():" + mServerIpAddress + "==" + mPort); + this.mSocket = new Socket(mServerIpAddress, mPort); + OutputStream os = this.mSocket.getOutputStream(); + mOutputStream = new BufferedOutputStream(os); } @Override diff --git a/app/src/main/java/com/gh/gamecenter/kuaichuan/IpPortInfo.java b/app/src/main/java/com/gh/gamecenter/kuaichuan/IpPortInfo.java index f038ec4b38..1bad096a1b 100644 --- a/app/src/main/java/com/gh/gamecenter/kuaichuan/IpPortInfo.java +++ b/app/src/main/java/com/gh/gamecenter/kuaichuan/IpPortInfo.java @@ -11,11 +11,13 @@ public class IpPortInfo implements Serializable { private InetAddress inetAddress; private int port; private String senderName; + private int senderIcon; - public IpPortInfo(InetAddress inetAddress, int port, String senderName) { + public IpPortInfo(InetAddress inetAddress, int port, String senderName, int senderIcon) { this.inetAddress = inetAddress; this.port = port; this.senderName = senderName; + this.senderIcon = senderIcon; } public InetAddress getInetAddress() { @@ -41,4 +43,12 @@ public class IpPortInfo implements Serializable { public void setSenderName(String senderName) { this.senderName = senderName; } + + public int getSenderIcon() { + return senderIcon; + } + + public void setSenderIcon(int senderIcon) { + this.senderIcon = senderIcon; + } } diff --git a/app/src/main/java/com/gh/gamecenter/personal/InstallFragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/personal/InstallFragmentAdapter.java index 540344e0ca..623dacaa56 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/InstallFragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/personal/InstallFragmentAdapter.java @@ -1,36 +1,49 @@ package com.gh.gamecenter.personal; import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; import android.support.v4.util.ArrayMap; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import com.gh.base.AppController; +import com.gh.common.constant.Config; import com.gh.common.constant.ItemViewType; +import com.gh.common.util.BitmapUtils; import com.gh.common.util.DataCollectionUtils; import com.gh.common.util.DataUtils; +import com.gh.common.util.DisplayUtils; import com.gh.common.util.DownloadItemUtils; import com.gh.common.util.GameUtils; import com.gh.common.util.GameViewUtils; import com.gh.common.util.PackageUtils; import com.gh.common.util.PlatformUtils; import com.gh.common.util.TrafficUtils; -import com.gh.common.view.CardLinearLayout; +import com.gh.common.view.SwipeLayout; import com.gh.download.DownloadManager; +import com.gh.gamecenter.ChooseReceiverActivity; import com.gh.gamecenter.R; import com.gh.gamecenter.adapter.viewholder.FooterViewHolder; -import com.gh.gamecenter.adapter.viewholder.GameNormalViewHolder; +import com.gh.gamecenter.adapter.viewholder.GameNormalSwipeViewHolder; import com.gh.gamecenter.db.LibaoDao; import com.gh.gamecenter.db.info.ConcernInfo; import com.gh.gamecenter.entity.ApkEntity; import com.gh.gamecenter.entity.GameEntity; import com.gh.gamecenter.entity.GameInfoEntity; +import com.gh.gamecenter.kuaichuan.FileInfo; import com.gh.gamecenter.manager.ConcernManager; import com.gh.gamecenter.manager.GameManager; import com.gh.gamecenter.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; +import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -60,8 +73,12 @@ class InstallFragmentAdapter extends RecyclerView.Adapter(); isRemove = false; + isSwipe = false; cardMargin = (int) context.getResources().getDimension(R.dimen.cardview_margin); libaoDao = new LibaoDao(context); + SharedPreferences sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); + showUserNameHint = sp.getBoolean("showUserNameHint", true); + ConcernManager cManager = new ConcernManager(context); List runnableGame = cManager.getInstalledGame(); if (runnableGame.isEmpty()) { @@ -310,20 +331,24 @@ class InstallFragmentAdapter extends RecyclerView.Adapter= 0 && position < gameList.size()) { return ItemViewType.GAME_NORMAL; } + + if (isRemove && !showUserNameHint) { + return ItemViewType.KC_HINT; + } + return ItemViewType.LOADING; } - private void initGameNormal(final GameNormalViewHolder holder, final GameEntity gameEntity, int i) { + private void initGameNormal(final GameNormalSwipeViewHolder holder, final GameEntity gameEntity, final int i) { // 第一个 if (i == 0) { - ((CardLinearLayout) holder.itemView).setmTop(cardMargin); + holder.cardView.setmTop(cardMargin); } else { - ((CardLinearLayout) holder.itemView).setmTop(0); + holder.cardView.setmTop(0); } // 最后一个 if (i == gameList.size() - 1) { - ((CardLinearLayout) holder.itemView).setBottom(true); + holder.cardView.setBottom(true); } else { - ((CardLinearLayout) holder.itemView).setBottom(false); + holder.cardView.setBottom(false); } + holder.swipeText.setPadding(0, 0, DisplayUtils.dip2px(context, 15), 0); holder.gameThumb.setImageURI(gameEntity.getIcon()); @@ -388,14 +422,16 @@ class InstallFragmentAdapter extends RecyclerView.Adapter kv = new HashMap<>(); - kv.put("名字", gameEntity.getName()); - kv.put("位置", String.valueOf(holder.getPosition() + 1)); - DataUtils.onEvent(context, "点击", "我的光环-已安装", kv); + if (!isSwipe) { + Map kv = new HashMap<>(); + kv.put("名字", gameEntity.getName()); + kv.put("位置", String.valueOf(holder.getPosition() + 1)); + DataUtils.onEvent(context, "点击", "我的光环-已安装", kv); - DataCollectionUtils.uploadClick(context, "列表", "我的光环-已安装", gameEntity.getName()); + DataCollectionUtils.uploadClick(context, "列表", "我的光环-已安装", gameEntity.getName()); - GameUtils.startGameDetailActivity(context, gameEntity.getId(), "(我的光环-已安装)"); + GameUtils.startGameDetailActivity(context, gameEntity.getId(), "(我的光环-已安装)"); + } } }); @@ -405,6 +441,94 @@ class InstallFragmentAdapter extends RecyclerView.Adapter 480) { + holder.swipeText.setPadding(0, 0, DisplayUtils.dip2px(context, 30), 0); + holder.swipeText.setText("释放分享"); + } else { + holder.swipeText.setPadding(0, 0, DisplayUtils.dip2px(context, 15), 0); + holder.swipeText.setText("右划分享"); + } + } + + @Override + public void onHandRelease(SwipeLayout layout, float xvel, float yvel) { + } + }); + } + + //跳转到快传 - 搜索接收者页面 + public void skipKc(int i) { + GameEntity gameEntity = gameList.get(i); + String packageName = gameEntity.getApk().get(0).getPackageName(); + PackageManager pm = context.getPackageManager(); + FileInfo fileInfo = new FileInfo(); + List installedPackages = pm.getInstalledPackages(0); + for (PackageInfo installedPackage : installedPackages) { + if ((installedPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 + && installedPackage.packageName.equals(packageName)) { + fileInfo.setFilePath(installedPackage.applicationInfo.sourceDir); + File file = new File(installedPackage.applicationInfo.sourceDir); + fileInfo.setSize(file.length()); + Drawable drawable = installedPackage.applicationInfo.loadIcon(pm); + fileInfo.setBitmap(BitmapUtils.drawableToBitmap(drawable)); + fileInfo.setFileTag(String.valueOf(System.currentTimeMillis())); + } + } + if (gameEntity.getApk() == null || gameEntity.getApk().isEmpty() + || gameEntity.getTag() == null || gameEntity.getTag().isEmpty()) { + fileInfo.setName(gameEntity.getName()); + } else { + fileInfo.setName(String.format("%s - %s", gameEntity.getName(), + PlatformUtils.getInstance(context).getPlatformName(gameEntity.getApk().get(0).getPlatform()))); + } + fileInfo.setPackageName(packageName); + List fileInfos = new ArrayList<>(); + fileInfos.add(fileInfo); + + AppController.put("FileInfo", fileInfos); + Intent intent = new Intent(context, ChooseReceiverActivity.class); + context.startActivity(intent); + + } + + public class KcHintViewHolder extends RecyclerView.ViewHolder { + + public KcHintViewHolder(View itemView) { + super(itemView); + } } } diff --git a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java index 440d700466..5761595550 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java +++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java @@ -37,9 +37,10 @@ import com.gh.common.util.DialogUtils; import com.gh.common.util.DisplayUtils; import com.gh.common.util.TokenUtils; import com.gh.common.util.Utils; -import com.gh.gamecenter.CropImageActivity; import com.gh.gamecenter.R; +import com.gh.gamecenter.SelectUserIconActivity; import com.gh.gamecenter.SettingActivity; +import com.gh.gamecenter.ShareGhActivity; import com.gh.gamecenter.adapter.FragmentAdapter; import com.gh.gamecenter.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; @@ -76,6 +77,7 @@ public class PersonalFragment extends Fragment implements View.OnClickListener, private TextView me_tv_top_concern; private TextView me_tv_top_name; private View me_top_slide_line; + private ImageView userNameHint; private RelativeLayout.LayoutParams top_line_rparams; @@ -84,6 +86,8 @@ public class PersonalFragment extends Fragment implements View.OnClickListener, private boolean isLogin; + private SharedPreferences sp; + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -96,22 +100,38 @@ public class PersonalFragment extends Fragment implements View.OnClickListener, view = View.inflate(getActivity(), R.layout.fragment_personal, null); + sp = getActivity().getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); + me_iv_top_icon = (SimpleDraweeView) view.findViewById(R.id.me_iv_top_icon); me_iv_top_icon.setOnClickListener(this); me_tv_top_name = (TextView) view.findViewById(R.id.me_tv_top_name); me_tv_top_name.setOnClickListener(this); + userNameHint = (ImageView) view.findViewById(R.id.user_name_hint); + + if (sp.getBoolean("showUserNameHint", true)) { + userNameHint.setVisibility(View.VISIBLE); + } + ImageView me_iv_top_setting = (ImageView) view.findViewById(R.id.me_iv_top_setting); + LinearLayout shareGhLl = (LinearLayout) view.findViewById(R.id.share_gh_ll); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) me_iv_top_setting.getLayoutParams(); params.topMargin = DisplayUtils.getStatusBarHeight(getResources()) + DisplayUtils.dip2px(getActivity(), 15); - me_iv_top_setting.setLayoutParams(params); - LinearLayout me_ll_info = (LinearLayout) view.findViewById(R.id.me_ll_info); + RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) shareGhLl.getLayoutParams(); + layoutParams.topMargin = DisplayUtils.getStatusBarHeight(getResources()) + + DisplayUtils.dip2px(getActivity(), 15); + + me_iv_top_setting.setLayoutParams(params); + shareGhLl.setLayoutParams(layoutParams); + + RelativeLayout me_ll_info = (RelativeLayout) view.findViewById(R.id.me_ll_info); me_ll_info.setPadding(0, DisplayUtils.getStatusBarHeight(getResources()), 0, 0); } me_iv_top_setting.setOnClickListener(this); + shareGhLl.setOnClickListener(this); DisplayMetrics outMetrics = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(outMetrics); @@ -172,7 +192,6 @@ public class PersonalFragment extends Fragment implements View.OnClickListener, @Override public void run() { if (getActivity() != null) { - SharedPreferences sp = getActivity().getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); String name = sp.getString("user_name", null); if (!TextUtils.isEmpty(name)) { me_tv_top_name.setText(name); @@ -245,13 +264,18 @@ public class PersonalFragment extends Fragment implements View.OnClickListener, DataCollectionUtils.uploadClick(getActivity(), "用户头像", "我的光环"); if (isLogin) { - Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); - startActivityForResult(intent, 0x123); +// Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); //TODO +// startActivityForResult(intent, 0x123); + Intent intent = new Intent(getContext(), SelectUserIconActivity.class); + startActivityForResult(intent, 0x125); } } else if (id == R.id.me_tv_top_install) { me_vp_show.setCurrentItem(0); } else if (id == R.id.me_tv_top_concern) { me_vp_show.setCurrentItem(1); + } else if (id == R.id.share_gh_ll) { + Intent intent = new Intent(getActivity(), ShareGhActivity.class); + getActivity().startActivity(intent); } } @@ -277,13 +301,12 @@ public class PersonalFragment extends Fragment implements View.OnClickListener, Utils.log("picturePath = " + picturePath); // 上传头像 - Intent intent = new Intent(getActivity(), CropImageActivity.class); - intent.putExtra("path", picturePath); - intent.putExtra("entrance", "(我的光环)"); - startActivityForResult(intent, 0x124); - } else if (data != null && requestCode == 0x124) { +// Intent intent = new Intent(getActivity(), CropImageActivity.class); +// intent.putExtra("path", picturePath); +// intent.putExtra("entrance", "(我的光环)"); +// startActivityForResult(intent, 0x124); + } else if (data != null && requestCode == 0x125) { String url = data.getExtras().getString("url"); - SharedPreferences sp = getActivity().getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); sp.edit().putString("user_icon", url).apply(); me_iv_top_icon.setImageURI(url); } @@ -329,6 +352,11 @@ public class PersonalFragment extends Fragment implements View.OnClickListener, confirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + if (userNameHint.getVisibility() == View.VISIBLE) { + userNameHint.setVisibility(View.GONE); + sp.edit().putBoolean("showUserNameHint", false).apply(); + } + String nickname = input.getText().toString().trim(); if (TextUtils.isEmpty(nickname)) { Toast.makeText(getActivity(), "请输入昵称", Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/res/drawable-hdpi/installfragment_footerview_icon.png b/app/src/main/res/drawable-hdpi/installfragment_footerview_icon.png new file mode 100644 index 0000000000..58b6cf8cc5 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/installfragment_footerview_icon.png differ diff --git a/app/src/main/res/drawable-hdpi/share_email_logo.png b/app/src/main/res/drawable-hdpi/share_email_logo.png index f26ccdd724..ba9db8520f 100644 Binary files a/app/src/main/res/drawable-hdpi/share_email_logo.png and b/app/src/main/res/drawable-hdpi/share_email_logo.png differ diff --git a/app/src/main/res/drawable-hdpi/share_gh_icon.png b/app/src/main/res/drawable-hdpi/share_gh_icon.png new file mode 100644 index 0000000000..0267a73687 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/share_gh_icon.png differ diff --git a/app/src/main/res/drawable-hdpi/user_default_icon1.png b/app/src/main/res/drawable-hdpi/user_default_icon1.png new file mode 100644 index 0000000000..dbd8f47c61 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_default_icon1.png differ diff --git a/app/src/main/res/drawable-hdpi/user_default_icon2.png b/app/src/main/res/drawable-hdpi/user_default_icon2.png new file mode 100644 index 0000000000..779cb0197d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_default_icon2.png differ diff --git a/app/src/main/res/drawable-hdpi/user_default_icon3.png b/app/src/main/res/drawable-hdpi/user_default_icon3.png new file mode 100644 index 0000000000..88162cbfd9 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_default_icon3.png differ diff --git a/app/src/main/res/drawable-hdpi/user_default_icon4.png b/app/src/main/res/drawable-hdpi/user_default_icon4.png new file mode 100644 index 0000000000..24b0f7d86e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_default_icon4.png differ diff --git a/app/src/main/res/drawable-hdpi/user_default_icon5.png b/app/src/main/res/drawable-hdpi/user_default_icon5.png new file mode 100644 index 0000000000..008ab86746 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_default_icon5.png differ diff --git a/app/src/main/res/drawable-hdpi/user_default_icon6.png b/app/src/main/res/drawable-hdpi/user_default_icon6.png new file mode 100644 index 0000000000..ea900db7df Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_default_icon6.png differ diff --git a/app/src/main/res/drawable-hdpi/user_default_icon7.png b/app/src/main/res/drawable-hdpi/user_default_icon7.png new file mode 100644 index 0000000000..f191f3842a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_default_icon7.png differ diff --git a/app/src/main/res/drawable-hdpi/user_default_icon8.png b/app/src/main/res/drawable-hdpi/user_default_icon8.png new file mode 100644 index 0000000000..2a36942f11 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_default_icon8.png differ diff --git a/app/src/main/res/drawable-hdpi/user_default_icon_bg.png b/app/src/main/res/drawable-hdpi/user_default_icon_bg.png new file mode 100644 index 0000000000..8061c54668 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_default_icon_bg.png differ diff --git a/app/src/main/res/drawable-xhdpi/user_name_hint.9.png b/app/src/main/res/drawable-xhdpi/user_name_hint.9.png new file mode 100644 index 0000000000..d8c5cc9504 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/user_name_hint.9.png differ diff --git a/app/src/main/res/drawable/game_item_btn_red_dn.xml b/app/src/main/res/drawable/game_item_btn_red_dn.xml index 30a5ab8040..ca609360b6 100644 --- a/app/src/main/res/drawable/game_item_btn_red_dn.xml +++ b/app/src/main/res/drawable/game_item_btn_red_dn.xml @@ -3,7 +3,7 @@ - + diff --git a/app/src/main/res/drawable/game_item_btn_red_up.xml b/app/src/main/res/drawable/game_item_btn_red_up.xml index 58766df7b4..4894a5cdcf 100644 --- a/app/src/main/res/drawable/game_item_btn_red_up.xml +++ b/app/src/main/res/drawable/game_item_btn_red_up.xml @@ -4,6 +4,6 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/share_gh_bg.xml b/app/src/main/res/drawable/share_gh_bg.xml new file mode 100644 index 0000000000..df177e3d3a --- /dev/null +++ b/app/src/main/res/drawable/share_gh_bg.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_choosereceiver.xml b/app/src/main/res/layout/activity_choosereceiver.xml index 30cbfdd8d5..e27f273dde 100644 --- a/app/src/main/res/layout/activity_choosereceiver.xml +++ b/app/src/main/res/layout/activity_choosereceiver.xml @@ -34,11 +34,10 @@ android:gravity="center" android:visibility="gone"> - + android:layout_height="40dp"/> - + android:layout_height="40dp"/> - + android:layout_height="40dp"/> - + android:layout_height="40dp"/> + android:paddingLeft="8dp"> + android:layout_marginRight="26dp"/> @@ -71,7 +71,7 @@ android:text="停止扫描" android:textSize="14sp" android:textColor="@android:color/white" - android:background="@drawable/game_item_btn_pause_style" + android:background="@drawable/game_item_btn_download_style" android:layout_alignParentBottom="true"/> diff --git a/app/src/main/res/layout/activity_file_sender.xml b/app/src/main/res/layout/activity_file_sender.xml index 3a5c3213ae..4b6f043ab4 100644 --- a/app/src/main/res/layout/activity_file_sender.xml +++ b/app/src/main/res/layout/activity_file_sender.xml @@ -59,9 +59,60 @@ - + android:layout_height="match_parent"> + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_kc_select_game.xml b/app/src/main/res/layout/activity_kc_select_game.xml index 7620c8e020..6b7113d34d 100644 --- a/app/src/main/res/layout/activity_kc_select_game.xml +++ b/app/src/main/res/layout/activity_kc_select_game.xml @@ -30,7 +30,7 @@ android:layout_alignParentRight="true" android:layout_centerVertical="true" style="@style/KcCheckboxStyle" - android:layout_marginRight="12dp"/> + android:layout_marginRight="26dp"/> @@ -44,14 +44,11 @@ + android:padding="10dp"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_share_gh.xml b/app/src/main/res/layout/activity_share_gh.xml index 879ea8dfb4..260823b9f2 100644 --- a/app/src/main/res/layout/activity_share_gh.xml +++ b/app/src/main/res/layout/activity_share_gh.xml @@ -9,35 +9,27 @@ + android:scrollbars="none" + android:background="@android:color/white"> - - + android:gravity="center_horizontal"> + android:layout_width="150dp" + android:layout_height="150dp" + android:layout_marginTop="20dp"/> -