我需要创建相同的按钮,如下图所示。 Button
必须包含内部文字。
当我进行XML
布局时,我遇到了Button
触摸区域的问题。每个下一个按钮都覆盖前一个带有矩形Button
区域的按钮。
像我一样在XML标记中放置六边形是否正确,以实现像图片中的六边形?请帮助我解决触摸区域的问题,如果可能,请告诉我如何正确创建布局,因为我不确定,因为我做的是正确的。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="?attr/actionBarSize">
<Button
android:id="@+id/button1"
android:layout_width="130dp"
android:layout_height="134dp"
android:background="@drawable/hexagon_shape_img"
android:text="Home page"
android:textSize="@dimen/small_text" />
<Button
android:id="@+id/button2"
android:layout_width="130dp"
android:layout_height="134dp"
android:layout_marginLeft="65dp"
android:layout_marginTop="-20dp"
android:background="@drawable/hexagon_shape_img"
android:text="Tavern"
android:textSize="@dimen/small_text" />
</LinearLayout>
答案 0 :(得分:2)
好吧,事实证明这比我想象的要复杂得多。基本问题是最高的Z-ordered按钮总是获得触摸事件,但是即使它没有处理事件,也不会在较低的Z-order上传递它。要获得两个按钮来查看事件,需要解决方法。这是基本方法:
1:在Fragment / Activity中创建一个当前包含十六进制按钮的容器
2:创建一个包含按钮的片段,以及所有这些按钮的另一个按钮,其中alpha = 0
3:添加一个getOverlay():返回该alpha = 0按钮的View方法
4:在片段中实现hitTest():Button方法
5:在主Activity / Fragment中,设置侦听器来处理叠加按钮的触摸事件
我制作(并测试过)一个应用程序来演示这个概念。我要把hitTest留给你,因为它很乏味
activity_main.xml中:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<FrameLayout android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
fragment_buttons.xml:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.me.testapplication.Buttons">
<Button android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lorem"/>
<Button android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lorem_ipsum"
android:alpha="0.4"/>
<Button android:id="@+id/overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"/>
</FrameLayout>
MainActivity.java:
public class MainActivity extends ActionBarActivity {
public static final String DEBUG_TAG = "TEST";
private Buttons mButtons;
private GestureDetector mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButtons = Buttons.newInstance();
getFragmentManager().beginTransaction()
.replace(R.id.main_container, mButtons)
.commit();
mGestureDetector = new GestureDetector(this, mGestureListener);
}
@Override
protected void onStart() {
super.onStart();
View overlay = mButtons.getOverlay();
if (overlay != null) {
overlay.setOnTouchListener(mTouchListener);
}
}
...
private View.OnTouchListener mTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
};
private GestureDetector.OnGestureListener mGestureListener
=new GestureDetector.OnGestureListener()
{
@Override
public boolean onDown(MotionEvent e) {
String buttonHit = mButtons.hitTest(e);
Log.i(DEBUG_TAG, buttonHit);
return true;
}
...
};
}
Buttons.java:
public class Buttons extends Fragment {
Button mButton1, mButton2;
View mOverlay;
public static Buttons newInstance() {
return new Buttons();
}
public Buttons() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_buttons, container, false);
mButton1 = (Button) root.findViewById(R.id.button1);
mButton2 = (Button) root.findViewById(R.id.button2);
mOverlay = root.findViewById(R.id.overlay);
return root;
}
@Nullable
public View getOverlay() {
return mOverlay;
}
public String hitTest(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if (x > mButton1.getLeft() && mButton1.getRight() > x &&
y > mButton1.getTop() && mButton1.getBottom() > y)
{
return "Button 1";
} else if (x > mButton2.getLeft() && mButton2.getRight() > x &&
y > mButton2.getTop() && mButton2.getBottom() > y)
{
return "Button 2";
} else {
return "None";
}
}
}
祝你好运。
ETA:示例hitTest
/**
* UNTESTED
* I'm going to assume square buttons (equilateral hexagons)
* this just calculates if the distance from the center of the button is less than its width. It may be good enough for government work.
*/
public View hitTest(MotionEvent e) {
for (Button hex : SomeIterableThingHoldingYourButtons) { //ArrayList<Button> maybe
float x = e.getX();
float y = e.getY();
if (isInHex(hex, x, y)) return hex;
}
return null;
}
private boolean isInHex(Button hex, float x, float y) {
float radius = hex.getRight() - hex.getLeft() / 2;
float centerX = hex.getLeft() + radius;
float centerY = hex.getTop() + radius;
float dist = FloatMath.sqrt(...) //euclidean distance
return dist < radius;
}