add support for recyclerView & Improve the interface

This commit is contained in:
Dacer
2016-11-18 16:22:48 +08:00
parent 5e8d6fbecd
commit c53fe07266
10 changed files with 205 additions and 52 deletions

View File

@@ -22,5 +22,6 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:recyclerview-v7:24.0.0'
compile 'com.jakewharton.timber:timber:4.3.1'
}

View File

@@ -3,6 +3,7 @@ package com.hackplan.androidarcmenu;
import android.app.Activity;
import android.graphics.Rect;
import android.support.annotation.DrawableRes;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -18,32 +19,35 @@ import java.util.HashSet;
public class ArcMenu {
public interface OnClickBtnListener{
void onClickArcMenu(View menuView, int viewId);
public interface OnClickMenuListener {
void onClickArcMenu(ArcMenu arcMenu, int clickedMenuId);
}
private ArcMenuInterceptLayout arcLayout;
private ArrayList<ArcButton.Builder> btnList;
private boolean hideOnTouchUp;
private Builder builder;
private ArcMenu(ArcMenuInterceptLayout arcLayout, ArrayList<ArcButton.Builder> btnList,
OnClickBtnListener listener, boolean hideOnTouchUp) {
this.arcLayout = arcLayout;
this.btnList = btnList;
this.hideOnTouchUp = hideOnTouchUp;
arcLayout.setOnClickBtnListener(listener);
private ArcMenu(Builder builder) {
this.builder = builder;
}
public void showOn(View view) {
if (view == null) return;
Rect rect = new Rect();
view.getGlobalVisibleRect(rect);
arcLayout.show(rect.centerX(), rect.centerY(), btnList, hideOnTouchUp);
builder.arcMenuLayout.show(this, rect.centerX(),
rect.centerY(),
builder.btnList,
builder.hideOnTouchUp);
}
public static class Builder implements View.OnTouchListener, View.OnLongClickListener{
public int getId() {
return builder.id;
}
public static class Builder{
private int id = -1;
private ArcMenu arcMenu;
private ArrayList<ArcButton.Builder> btnList = new ArrayList<>();
private OnClickBtnListener onClickBtnListener;
private OnClickMenuListener onClickMenuListener;
private Activity activity;
private ArcMenuInterceptLayout arcMenuLayout;
private HashSet<View> onTouchViews = new HashSet<>();
@@ -55,12 +59,20 @@ public class ArcMenu {
}
public ArcMenu build() {
if (arcMenu != null) throw new RuntimeException("ArcMenu.Build already built");
arcMenuLayout = attachToActivity(activity);
return new ArcMenu(arcMenuLayout, btnList, onClickBtnListener, hideOnTouchUp);
arcMenuLayout.setOnClickBtnListener(onClickMenuListener);
arcMenu = new ArcMenu(this);
return arcMenu;
}
public Builder setListener(OnClickBtnListener listener) {
this.onClickBtnListener = listener;
public Builder setId(int id){
this.id = id;
return this;
}
public Builder setListener(OnClickMenuListener listener) {
this.onClickMenuListener = listener;
return this;
}
@@ -76,13 +88,13 @@ public class ArcMenu {
public Builder showOnTouch(View view) {
onTouchViews.add(view);
view.setOnTouchListener(this);
view.setOnTouchListener(touchListener);
return this;
}
public Builder showOnLongClick(View view) {
view.setOnTouchListener(this);
view.setOnLongClickListener(this);
view.setOnTouchListener(touchListener);
view.setOnLongClickListener(longClickListener);
return this;
}
@@ -91,27 +103,34 @@ public class ArcMenu {
return this;
}
@Override
public boolean onLongClick(View v) {
arcMenuLayout.show(lastTouchX, lastTouchY, btnList, hideOnTouchUp);
return true;
}
private View.OnLongClickListener longClickListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
arcMenuLayout.show(arcMenu, lastTouchX, lastTouchY, btnList, hideOnTouchUp);
return true;
}
};
private int lastTouchX, lastTouchY;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
if (onTouchViews.contains(v)) {
arcMenuLayout.show((int) event.getRawX(), (int) event.getRawY(),
btnList, hideOnTouchUp);
}else {
//Used in onLongClick(View v)
lastTouchX = (int) event.getRawX();
lastTouchY = (int) event.getRawY();
private View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
if (onTouchViews.contains(v)) {
arcMenuLayout.show(arcMenu,
(int) event.getRawX(),
(int) event.getRawY(),
btnList, hideOnTouchUp);
}else {
//Used in onLongClick(View v)
lastTouchX = (int) event.getRawX();
lastTouchY = (int) event.getRawY();
}
}
return false;
}
return false;
}
};
ArcMenuInterceptLayout attachToActivity(Activity activity) {
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();

View File

@@ -5,7 +5,7 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import com.hackplan.androidarcmenu.ArcMenu.OnClickBtnListener;
import com.hackplan.androidarcmenu.ArcMenu.OnClickMenuListener;
import java.util.ArrayList;
@@ -35,7 +35,7 @@ public class ArcMenuInterceptLayout extends FrameLayout {
childViewParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
public void show(int x, int y, ArrayList<ArcButton.Builder> btnList, boolean hideOnTouchUp) {
public void show(ArcMenu arcMenu, int x, int y, ArrayList<ArcButton.Builder> btnList, boolean hideOnTouchUp) {
if (indexOfChild(arcMenuLayout) == -1) {
addView(arcMenuLayout);
}
@@ -43,12 +43,12 @@ public class ArcMenuInterceptLayout extends FrameLayout {
for (ArcButton.Builder builder : btnList) {
arcMenuLayout.addView(builder.getButton(getContext()), childViewParams);
}
arcMenuLayout.show(x, y, hideOnTouchUp);
arcMenuLayout.show(arcMenu, x, y, hideOnTouchUp);
}
public void setOnClickBtnListener(OnClickBtnListener onClickBtnListener) {
arcMenuLayout.setOnClickBtnListener(onClickBtnListener);
public void setOnClickBtnListener(OnClickMenuListener onClickMenuListener) {
arcMenuLayout.setOnClickMenuListener(onClickMenuListener);
}
@Override

View File

@@ -16,7 +16,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import com.hackplan.androidarcmenu.ArcMenu.OnClickBtnListener;
import com.hackplan.androidarcmenu.ArcMenu.OnClickMenuListener;
/**
* Created by Dacer on 12/11/2016.
@@ -26,7 +26,8 @@ public class ArcMenuLayout extends ViewGroup {
private Point touchPoint = new Point();
private final Rect mScreenRect = new Rect();
private Rect tempRect = new Rect();
private OnClickBtnListener onClickBtnListener;
private ArcMenu arcMenu;
private OnClickMenuListener onClickMenuListener;
private boolean show = false;
private boolean hideOnTouchUp = true;
@@ -49,8 +50,9 @@ public class ArcMenuLayout extends ViewGroup {
private float xFirst, yFirst, xEnd, yEnd;
private int radius = (int)dpToPx(80f);
private double radAlpha = Math.toRadians(90d);
public void show(int x, int y, boolean hideOnTouchUp) {
public void show(ArcMenu arcMenu, int x, int y, boolean hideOnTouchUp) {
this.hideOnTouchUp = hideOnTouchUp;
this.arcMenu = arcMenu;
show = true;
touchPoint.set(x, y);
double radO = Math.PI - radAlpha/2 -
@@ -63,8 +65,8 @@ public class ArcMenuLayout extends ViewGroup {
requestLayout();
}
public void setOnClickBtnListener(OnClickBtnListener onClickBtnListener) {
this.onClickBtnListener = onClickBtnListener;
public void setOnClickMenuListener(OnClickMenuListener onClickMenuListener) {
this.onClickMenuListener = onClickMenuListener;
}
@Override
@@ -119,9 +121,9 @@ public class ArcMenuLayout extends ViewGroup {
if (lastFocusIndex != -1) {
show = false;
AnimatorUtils.openMenu(this, lastFocusIndex, animListener);
if (onClickBtnListener != null) {
if (onClickMenuListener != null) {
View clickedView = getChildAt(lastFocusIndex);
onClickBtnListener.onClickArcMenu(clickedView, (int)clickedView.getTag());
onClickMenuListener.onClickArcMenu(arcMenu, (int)clickedView.getTag());
}
} else if (hideOnTouchUp) {
AnimatorUtils.hideMenu(this, touchPoint);

View File

@@ -0,0 +1,42 @@
/**
* Copyright (C) 2015 ogaclejapan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hackplan.androidarcmenu;
/**
* Modified by Dacer.
* from https://github.com/ogaclejapan/ArcLayout
*/
public class Utils {
public static int x(int radius, float degrees) {
return Math.round(Utils.computeCircleX(radius, degrees));
}
public static int y(int radius, float degrees) {
return Math.round(computeCircleY(radius, degrees));
}
private static float computeCircleX(float r, float degrees) {
return (float) (r * Math.cos(Math.toRadians(degrees)));
}
private static float computeCircleY(float r, float degrees) {
return (float) (r * Math.sin(Math.toRadians(degrees)));
}
}

View File

@@ -23,6 +23,7 @@ dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile project(':androidarcmenu')
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:recyclerview-v7:24.0.0'
compile 'com.jakewharton.timber:timber:4.3.1'
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'

View File

@@ -2,6 +2,8 @@ package com.hackplan.androidarcmenu.demo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
@@ -9,8 +11,11 @@ import android.widget.Toast;
import com.hackplan.androidarcmenu.ArcButton;
import com.hackplan.androidarcmenu.ArcMenu;
public class MainActivity extends AppCompatActivity implements ArcMenu.OnClickBtnListener, View.OnLongClickListener{
public class MainActivity extends AppCompatActivity implements ArcMenu.OnClickMenuListener,
View.OnLongClickListener{
private ArcMenu arcMenu, arcMenu2;
public static final int ARC_MENU_ID_1 = 1;
public static final int ARC_MENU_ID_2 = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -20,10 +25,12 @@ public class MainActivity extends AppCompatActivity implements ArcMenu.OnClickBt
final Button btn2 = (Button) findViewById(R.id.btn2);
final Button btn3 = (Button) findViewById(R.id.btn3);
final Button btn4 = (Button) findViewById(R.id.btn4);
final RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
Button menuBtn = new Button(this);
menuBtn.setText("TEST");
arcMenu = new ArcMenu.Builder(MainActivity.this)
.setId(ARC_MENU_ID_1)
.addBtn(R.drawable.a, 0)
.addBtn(R.drawable.r, 1)
.setListener(MainActivity.this)
@@ -32,6 +39,7 @@ public class MainActivity extends AppCompatActivity implements ArcMenu.OnClickBt
.build();
arcMenu2 = new ArcMenu.Builder(MainActivity.this)
.setId(ARC_MENU_ID_2)
.addBtn(R.drawable.w, 6)
.addBtns(new ArcButton.Builder(menuBtn, 2))
.setListener(MainActivity.this)
@@ -46,11 +54,18 @@ public class MainActivity extends AppCompatActivity implements ArcMenu.OnClickBt
arcMenu.showOn(v);
}
});
LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
MyAdapter mAdapter = new MyAdapter(new String[]{"Pomotodo", "hackplan", "http://one.hackplan.com/", "Dacer"}, this, this);
mRecyclerView.setAdapter(mAdapter);
}
@Override
public void onClickArcMenu(View menuView, int id) {
Toast.makeText(this, String.format("Click #%s", id), Toast.LENGTH_SHORT).show();
public void onClickArcMenu(ArcMenu arcMenu, int viewId) {
Toast.makeText(this, String.format("Click #%s, arcMenu id: %s", viewId, arcMenu.getId()), Toast.LENGTH_SHORT).show();
}
@Override
@@ -58,4 +73,5 @@ public class MainActivity extends AppCompatActivity implements ArcMenu.OnClickBt
arcMenu.showOn(v);
return true;
}
}

View File

@@ -0,0 +1,58 @@
package com.hackplan.androidarcmenu.demo;
import android.app.Activity;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.hackplan.androidarcmenu.ArcMenu;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private String[] mDataset;
private ArcMenu.Builder builder;
public static final int ARC_MENU_ID_3 = 3;
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(TextView v) {
super(v);
mTextView = v;
}
}
public MyAdapter(String[] myDataset, Activity activity, ArcMenu.OnClickMenuListener listener) {
mDataset = myDataset;
builder = new ArcMenu.Builder(activity)
.setId(ARC_MENU_ID_3)
.addBtn(R.drawable.a, 0)
.addBtn(R.drawable.r, 1)
.setListener(listener)
.hideOnTouchUp(false);
builder.build();
}
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
TextView tv = (TextView)LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row, parent, false);
return new ViewHolder(tv);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView.setText(mDataset[position]);
builder.showOnLongClick(holder.mTextView);
}
@Override
public int getItemCount() {
return mDataset.length;
}
}

View File

@@ -39,4 +39,12 @@
android:layout_above="@+id/btn3"
android:layout_marginBottom="20dp"
android:text="btn4"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_below="@+id/btn3"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="20dp" />