2

I would like to change the back/home button icon in Titanium. I am able to do this using the Theme.

However I would like to change the icon at runtime after I apply the theme. The actionbar in titanium does not have any property or method to change the icon. Documentation. So I am using the hyperloop (native code) to change the icon, but unfortunately I am not able to access the actionbar.

Here is my view

<Alloy>
    <Window class="container">
        <ActionBar id="actionbar" displayHomeAsUp="true" homeButtonEnabled="true"></ActionBar>
        <Label id="label" onClick="doClick">Hello, World</Label>
    </Window>
</Alloy>

My code

import AppCompatActivity from 'android.support.v7.app.AppCompatActivity';
const activity = new AppCompatActivity(Ti.Android.currentActivity);
activity.getActionBar().setHomeAsUpIndicator(Titanium.Android.R.drawable.notificacion);

And the error

[ERROR] TiExceptionHandler: (main) [1,434] /alloy/controllers/index.js:69
[ERROR] TiExceptionHandler:   activity.getActionBar().setHomeAsUpIndicator(Titanium.Android.R.drawable.notificacionmas);
[ERROR] TiExceptionHandler:                           ^
[ERROR] TiExceptionHandler: TypeError: activity.getActionBar(...).setHomeAsUpIndicator is not a function
[ERROR] TiExceptionHandler:     at new Controller (/alloy/controllers/index.js:69:27)
[ERROR] TiExceptionHandler:     at Object.exports.createController (/alloy.js:428:10)
[ERROR] TiExceptionHandler:     at /app.js:22:7
[ERROR] TiExceptionHandler:     at Module._runScript (ti:/module.js:608:9)
[ERROR] TiExceptionHandler:     at Module.load (ti:/module.js:107:7)
[ERROR] TiExceptionHandler:     at Module.loadJavascriptText (ti:/module.js:453:9)
[ERROR] TiExceptionHandler:     at Module.loadAsFile (ti:/module.js:508:15)
[ERROR] TiExceptionHandler:     at Module.loadAsFileOrDirectory (ti:/module.js:425:20)
[ERROR] TiExceptionHandler:     at Module.require (ti:/module.js:255:17)
[ERROR] TiExceptionHandler:     at Module.global.Module.require (/ti.main.js:11435:34)
[ERROR] TiExceptionHandler:
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:162)
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.KrollRuntime.runModule(KrollRuntime.java:207)
[ERROR] TiExceptionHandler:     org.appcelerator.titanium.TiLaunchActivity.loadScript(TiLaunchActivity.java:99)
[ERROR] TiExceptionHandler:     org.appcelerator.titanium.TiRootActivity.loadScript(TiRootActivity.java:480)
[ERROR] TiExceptionHandler:     org.appcelerator.titanium.TiLaunchActivity.onResume(TiLaunchActivity.java:183)
[ERROR] TiExceptionHandler:     org.appcelerator.titanium.TiRootActivity.onResume(TiRootActivity.java:499)
[ERROR] TiExceptionHandler:     android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1446)
[ERROR] TiExceptionHandler:     android.app.Activity.performResume(Activity.java:7939)
[ERROR] TiExceptionHandler:     android.app.ActivityThread.performResumeActivity(ActivityThread.java:4195)
[ERROR] V8Exception: Exception occurred at /alloy/controllers/index.js:69: Uncaught TypeError: activity.getActionBar(...).setHomeAsUpIndicator is not a function

Note

I believe this question is not a duplicate, since it is related to Titanium and not native Android.

halfer
  • 19,824
  • 17
  • 99
  • 186
Searock
  • 6,278
  • 11
  • 62
  • 98
  • 1
    I have an example that uses a custom XML layout where I specify the Actionbar and access it via code: https://github.com/m1ga/hyperloop.collapsingToolbarLayout if that is an option for you you could try to change the icon there – miga Nov 29 '19 at 23:01
  • 1
    I'm having the same issue right now. Looks like Hyperloop expects you to use android.app.Activity, even though Titanium uses the support library (at least before 9.0.0), and the Activity doesn't return an ActionBar with getActionBar(). Really frustrating that Titanium just doesn't expose the setHomeAsUpIndicator() method. Both setIcon and setLogo do not set the actual button drawable. – cr0ybot Feb 05 '20 at 18:08
  • FYI I tried using android.support.v7.app.AppCompatActivity and getSupportActionBar(). It returns an ActionBar instance, but doesn't seem to be tied to the actual ActionBar. – cr0ybot Feb 05 '20 at 18:50
  • @cr0ybo I got tired and gave up. I just needed this in one screen. The client wanted to replace the home button with the notification button. So I hid the actionbar and put a view that look liked an action bar. – Searock Feb 06 '20 at 02:53
  • @miga Thanks for your help. I used some of your code but unfortunately I was not able to set the icon. I guess I was passing the reference to the drawable in a wrong way. – Searock Feb 06 '20 at 02:55
  • @Searock I've added an answer with a full example. Hope it helps – miga Feb 06 '20 at 18:20

2 Answers2

1

I've updated my Hyperloop example at https://github.com/m1ga/hyperloop.collapsingToolbarLayout

It's using a custom back icon in the "collapsing toolbar" example screen. I've added a icon xml:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FFFFFF00"
        android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zm-8,0c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zm0,2c-2.33,0 -7,1.17 -7,3.5V19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zm8,0c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45V19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z"/>
</vector>

and assigning it with

toolbar.setNavigationIcon(resIDFromString("ic_action_users", "drawable"));

(https://github.com/m1ga/hyperloop.collapsingToolbarLayout/blob/master/app/controllers/second.js#L44)

The full example is inside the repo

miga
  • 3,997
  • 13
  • 45
0

There is absolutely no need of Hyperloop for this.

You can communicate with the actionBar using the activity https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Android.Activity

Then you can fetch the actionBar from the activity, and then change the icon using the icon property of the actionBar

Make sure to do this only after the window has triggered the open event though.

window.addEvenListener('open', e => {
  var actionbar = window.activity.actionBar;
  actionbar.icon = '/images/upicon.png'; 
});
Searock
  • 6,278
  • 11
  • 62
  • 98
Rene Pot
  • 24,681
  • 7
  • 68
  • 92
  • 1
    This changes the application icon and not the back button. This could have worked for me if I just had to display an icon and not interact with the icon. Thanks. +1 – Searock Nov 29 '19 at 14:37