Ask*_*ion 5 xml android button
我需要创建相同的按钮,如下图所示.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>
Run Code Online (Sandbox Code Playgroud)
好吧,结果比我想象的要复杂。基本问题是最高 Z 顺序的按钮始终会获取触摸事件,但不会将其传递给较低 Z 顺序的按钮,即使它不处理该事件也是如此。要让两个按钮都能看到事件,需要解决方法。这是基本方法:
1:在当前保存十六进制按钮的片段/活动中创建一个容器
2:创建一个包含按钮和所有按钮之上的另一个按钮(alpha=0)的片段
3:添加一个 getOverlay():View 方法,返回 alpha=0 按钮
4:在fragment中实现一个hitTest():Button方法
5:在主Activity/Fragment中,设置监听器来处理覆盖按钮的触摸事件
我制作(并测试)了一个应用程序来演示这个概念。我将把 hitTest 留给你,因为它相当乏味
活动_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>
Run Code Online (Sandbox Code Playgroud)
片段_按钮.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>
Run Code Online (Sandbox Code Playgroud)
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;
}
...
};
}
Run Code Online (Sandbox Code Playgroud)
按钮.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";
}
}
}
Run Code Online (Sandbox Code Playgroud)
祝你好运。
ETA:命中测试示例
/**
* 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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3243 次 |
| 最近记录: |