mirror of
https://github.com/HackPlan/AndroidArcMenu.git
synced 2026-06-15 23:12:40 +08:00
add support for recyclerView & Improve the interface
This commit is contained in:
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
6
app/src/main/res/layout/list_row.xml
Normal file
6
app/src/main/res/layout/list_row.xml
Normal 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" />
|
||||
Reference in New Issue
Block a user