Android button - How to set focusable to true and still accept onClick listener on first click?

Viewed 20142

UPDATE

I've solved the clicking issue by removing the two focusable lines from the button style and using the onClick event handler to call requestFocusFromTouch();

Unfortunately I'm left with an issue that requestFocusFromTouch() focuses the wrong button. It always focuses the first button not the button I call the method on. Is this an android bug or expected behaviour and what I can I do for a work around?

The code now looks like this for the onClick event

public void onClick(View v) {
    switch (v.getId()) {
            case R.id.btn_home:
                Intent i = new Intent(this, QuizMenu.class);
                startActivity(i);
                v.requestFocusFromTouch();
            break;
            case R.id.btn_support:
                Intent i1 = new Intent(this, Support.class);
                startActivity(i1);
                v.requestFocusFromTouch();
                View btnSupport = findViewById(R.id.btn_support);
                btnSupport.setSelected(true);
                btnSupport.requestFocusFromTouch();
            break;
            // More buttons go here (if any) ...
    }
}

END OF UPDATE

I have an android button that has the following style

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MnuBtnStyle">
        <item name="android:ellipsize">marquee</item>
        <item name="android:scrollHorizontally">true</item>
        <item name="android:focusable">true</item>
        <item name="android:focusableInTouchMode">true</item>
        <item name="android:singleLine">true</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_marginTop">1dip</item> 
        <item name="android:layout_marginBottom">1dip</item>
        <item name="android:textSize">10dp</item>
        <item name="android:layout_weight">1</item>
        <item name="android:textColor">#00FF00</item>
        <item name="android:typeface">monospace</item>
    </style>
</resources>

I have an on click listener that looks like this

public void onClick(View v) {
    switch (v.getId()) {
            case R.id.btn_home:
                Intent i = new Intent(this, HomeScreen.class);
                startActivity(i);
            break;
            // More buttons go here ...
    }
}

I have an image on the button and the selector looks like this

<?xml version="1.0" encoding="utf-8"?>
<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
        android:drawable="@drawable/ic_tab_home_pressed" /> <!-- pressed -->
    <item android:state_focused="true"
        android:drawable="@drawable/ic_tab_home_pressed" /> <!-- pressed -->
    <item android:drawable="@drawable/ic_tab_home_unpressed" /> <!-- default/unchecked -->
</selector>

The layout that uses the button and the button looks like this

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:id="@+id/top_menu_bar"
      android:layout_marginTop="2dip" 
      android:padding="0dip"
      android:background="@android:drawable/bottom_bar"
      android:layout_alignParentTop="true"
      android:gravity="top"
      android:layout_height="@dimen/menu_bar_height"
      android:layout_width="fill_parent">
      <Button
          android:id="@+id/btn_home"
          android:text="@string/btn_home"
          android:drawableTop="@drawable/home_button"
          style="@style/MnuBtnStyle"
      />
...

there are other buttons and this layout is acting as a top menu bar that is included in whatever layout needs it.

The onClick event for the button is only fired on second click of the button due to the focusable lines.

        <item name="android:focusable">true</item>
        <item name="android:focusableInTouchMode">true</item>

The first click sets focus on the button then the second click fires the onClick event listener I need to combine the two together so that the first click sets focus AND fires the onClick event listener. Can this be done?

If I remove the two focusable lines the buttons behave normally but I want to show that the button is focused and I want the scrolling text inside the button that <item name="android:ellipsize">marquee</item> gives me

Any ideas greatly appreciated

3 Answers
Related