17

Background

I wish to show an ActionBar on PreferenceActivity, as it's not available for pre-Honeycomb devices (even in the support library).

Because such a class isn't available on the support library, I can't just call "setSupportActionBar" . I also don't wish to use a library (like this one) since all of the libraries I've found still use Holo style, so they didn't get updated so far, with this in mind.

To do this, I'm trying to mimic the look&feel of the title of the ActionBar into the new Toolbar class, that was presented on support library v7 .

The problem

I've succeeded putting a title and a an "up" button, but I can't find out how to make them clickable like a normal action bar, including the effect of touching.

The code

Here's the code:

SettingsActivity.java

public class SettingsActivity extends PreferenceActivity
  {
  @Override
  protected void onCreate(final Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_settings);
    addPreferencesFromResource(R.xml.pref_general);
    final Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
    toolbar.setBackgroundColor(getResources().getColor(R.color.windowBackgroundColor));
    toolbar.setTitle("Settings");
    toolbar.setClickable(true);
    toolbar.setLogo(getResIdFromAttribute(this,R.attr.homeAsUpIndicator));
    }

  public static int getResIdFromAttribute(final Activity activity,final int attr)
    {
    if(attr==0)
      return 0;
    final TypedValue typedvalueattr=new TypedValue();
    activity.getTheme().resolveAttribute(attr,typedvalueattr,true);
    return typedvalueattr.resourceId;
    }
  }

activity_settings.xml

<LinearLayout 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:orientation="vertical"
    tools:context="com.antonioleiva.materialeverywhere.SettingsActivity" >

    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <View
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/abs__ab_solid_shadow_holo" />

        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>

</LinearLayout>

What I've tried

I've tried all of the click listeners types of the Toolbar class, but none helped.

The only thing that almost worked is to use "setNavigationIcon" instead of "setLogo", but that actually makes the title&icon being clicakable, yet only the icon shows its effect of being clicked (even if I click on the title).

The question

How can I add the look & feel of the Toolbar, to have the title & logo of it to look like the ActionBar?

1
  • I ended up by leaving the real ActionBar where it is (in the one only Activity I have) and simulating the PreferenceScreen. Now this is actually just another Fragment in which I recreate the look and feel of the standard PreferenceActivity elements. Commented Oct 22, 2014 at 7:14

4 Answers 4

34

I had the same problem and found a quite convenient way for it (for the clickable title), doing this with the Toolbar. It does not matter, if the Toolbaris used as ActionBar or not, it works for both cases.

Just set the click listener on the Toolbar itself, this will result in the complete Toolbarfiring the click listener, if not a menu item or the home icon is clicked. For me, that's exactly what I expect...

For example:

 setSupportActionBar(toolbar);
 getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 toolbar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(getThis(), "Toolbar title clicked", Toast.LENGTH_SHORT).show();
        }
    });

onOptionsItemSelected, home click and similar WON'T fire the onClick event. Seems like a good solution

5
  • Wouldn't it get fired when clicking on empty spaces in the toolbar? Commented Nov 4, 2015 at 12:57
  • It will, but that space would be filled by a textview with MATCH_PARENT as well... it's fine for my usecases...
    – prom85
    Commented Nov 4, 2015 at 13:00
  • @prom85 how do you add the textview with h match_parent? if I add a view with match_parent it will cover the title.
    – amarkovits
    Commented Nov 11, 2015 at 15:23
  • I did this as I wanted to use this text view instead of a title . If you don't need the text view don't use it? Or do you need it?
    – prom85
    Commented Nov 11, 2015 at 15:31
  • 2
    This is a great solution. There is no need to add anything to the xml for the toolbar, i.e. no need for TextView or ImageView. What I did was to set a logo with getSupportActionBar().setLogo(R.drawable.jclogo);, make it clickable: toolbar.setClickable(true);, followed by the code above and it works perfect. Thank you @prom85 Commented Aug 10, 2017 at 9:30
24

Just remember that the Toolbar is basically just a ViewGroup so you can add a TextView to it and listen to onClick events like that.

Add TextView to Toolbar in XML:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_top"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="@color/action_bar_bkgnd"
    app:theme="@style/ToolBarTheme" >


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Settings"
        android:id="@+id/toolbar_title" />

    </android.support.v7.widget.Toolbar>

Listen for clicks in your Activity:

toolbarTop.findViewById(R.id.toolbar_title).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d(TAG,"Clicked");
        }
    });
14
  • I want it to look like the normal actionbar that I use on other activities, and maybe be able to add an actionItem (for a different preferenceActivity that I use for widgets). You can try out my app if it's hard to imagine it : play.google.com/store/apps/details?id=com.lb.app_manager . About clicking on the text, I've now noticed that this has changed in material design, and only the "up" button should be clickable, but in the current approach the title is clickable (yet as I said, doesn't have an effect of clicking) and I can't make it un-clickable Commented Oct 22, 2014 at 21:20
  • So you question is about how to make the text look more like the Actionbar text and not be clickable? Commented Oct 22, 2014 at 21:48
  • Yes, preferably making it entirely look and behave like a normal ActionBar. If it's impossible to make the textView un-clickable, at least set it the same effect of clicking like on the "up" button. Commented Oct 22, 2014 at 22:26
  • On what device is it clickable? Commented Oct 22, 2014 at 22:30
  • on mine: SGS3 (I9300) with custom rom CM (Android 4.4.x) . When I click on the title, the "up" button also gets clicked (or at least has an effect of being clicked). Commented Oct 22, 2014 at 23:05
1

You can actually do it pretty easily without having to do any workarounds. You just need to cycle through all the child views of the Toolbar, and find a TextView that's got the correct title text.

String title = toolbar.getTitle();
for(int i = 0; i < toolbar.getChildCount(); i++){
    View tmpView = toolbar.getChildAt(i);
    if("android.support.v7.widget.AppCompatTextView".equals(tmpView.getClass().getName())){
        if(((AppCompatTextView) tmpView).getText().equals(title)){
            tmpView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //do whatever you want here
                }
            });
        }
    }
}
2
  • Comparing values (text title in this case) is usually a bad idea because the title can change, and because multiple elements might have the same value, or the title can be an empty string. Commented Jul 23, 2023 at 15:16
  • That's not a problem. We're checking the title right before cycling through the views, so the title would have to change in the spit-second between those 2 actions, and that's virtually never gonna happen
    – user496854
    Commented Jul 30, 2023 at 0:22
1

After setting up not empty toolbar title try this for setting title click listener

    if (toolbarView != null) {
        int childCount = toolbarView.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = toolbarView.getChildAt(i);
            if (view instanceof TextView) {
                view.setOnClickListener(listener);
                break;
            }
        }
    }

and after setting up not empty toolbar subtitle for setting subtitle click listener

    if (toolbarView != null) {
        int childCount = toolbarView.getChildCount();
        for (int i = childCount - 1; i >= 0; i--) {
            View view = toolbarView.getChildAt(i);
            if (view instanceof TextView) {
                view.setOnClickListener(listener);
                break;
            }
        }
    }

Not the answer you're looking for? Browse other questions tagged or ask your own question.