Giter VIP home page Giter VIP logo

Comments (13)

nhaarman avatar nhaarman commented on June 16, 2024

Could you provide some sample code of how you're creating the views?

Note that views should be created using the Activity context which contains the proper theme, and when not created from XML you should pass the proper defStyleAttr to the View's constructor (e.g. android.R.attr.textViewStyle for TextView).

Whether or not setContentView is used should not play any role here.

from acorn.

gumil avatar gumil commented on June 16, 2024

Views are created using ViewProvidingScene's createViewController parent context parameter. The colors were not inherited like colorPrimary when Acorn was used. But setting the view directly to setContentView it got the right colors.

from acorn.

nhaarman avatar nhaarman commented on June 16, 2024

Are you using AcornAppCompatActivity?

from acorn.

gumil avatar gumil commented on June 16, 2024

Yes, and I am relying to the colorPrimary etc.

from acorn.

nhaarman avatar nhaarman commented on June 16, 2024

Hm, this should work actually. The parent: ViewGroup provided in ViewProvidingScene is derived from the FrameLayout provided by the system through android.R.id.content, which obviously contains the theme info as necessary.

Activity.setContentView delegates to PhoneWindow.setContentView, which uses the same Activity context instance as provided through the parent instance, so there's no further magic happening there to make themes work.

Without a reproducible example there's not really much to go on from here. Would it be possible to create a sample project that consistently reproduces the issue?

from acorn.

gumil avatar gumil commented on June 16, 2024

With Acorn Scenes:
Screenshot_1568651983

class MainActivity : AcornAppCompatActivity() {
    override fun provideNavigatorProvider(): NavigatorProvider {
        return DemoNavigatorProvider
    }
}

setContentView:
Screenshot_1568652005

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(HomeView(this, DemoModel.values().toList()))
    }
}

The whole code is here https://github.com/gumil/acorn-demo

from acorn.

nhaarman avatar nhaarman commented on June 16, 2024

Thanks! That should help a lot.

from acorn.

nhaarman avatar nhaarman commented on June 16, 2024

The issue is more easily reproduced like so:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //setContentView(TextView(this).apply { text = "HELLO WORLD" })
        setContentView(TextView(findViewById<ViewGroup>(R.id.content).context).apply { text = "HELLO WORLD" })
    }
}

The assumption I made earlier is that the Context passed was the same instance in both cases seems to be wrong: the second instance (from the android.R.id.content View) is a ContextThemeWrapper.
The baseContext of this wrapper is in fact the MainActivity instance, so this 'fixes' the theming issue again:

 val context = (findViewById<ViewGroup>(R.id.content).context as ContextThemeWrapper).baseContext
 setContentView(TextView(context).apply { text = "HELLO WORLD" })

from acorn.

nhaarman avatar nhaarman commented on June 16, 2024

It seems AppCompat does some hacky things under the hood, by removing the android.R.id.content id from the original View and applying it to its own view:

https://android.googlesource.com/platform/frameworks/support/+/d25af35/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV7.java#390

// Change our content FrameLayout to use the android.R.id.content id.
// Useful for fragments.
decorContent.setId(View.NO_ID);
abcContent.setId(android.R.id.content);

This abcContent View is created using an 'emulated' ContextThemeWrapper:

/**
--
* This needs some explanation. As we can not use the android:theme attribute
* pre-L, we emulate it by manually creating a LayoutInflater using a
* ContextThemeWrapper pointing to actionBarTheme.
*/
TypedValue outValue = new TypedValue();
mContext.getTheme().resolveAttribute(R.attr.actionBarTheme, outValue, true);
themedContext = new ContextThemeWrapper(mContext, outValue.resourceId);

This ContextThemeWrapper is the instance we're seeing in our issue here, which resolves to the ActionBarTheme and not the app's theme..

I'm not sure yet why LayoutInflater.from that ContextThemeWrapper uses proper theming though (which is why I haven't seen this issue before).

from acorn.

nhaarman avatar nhaarman commented on June 16, 2024

A quick-and-dirty fix could be to insert a FrameLayout in between with the proper Context instance like so:

class MainActivity : AcornAppCompatActivity() {

    private lateinit var rootView: ViewGroup

    override fun onCreate(savedInstanceState: Bundle?) {
        rootView = FrameLayout(this)
        setContentView(rootView)
        super.onCreate(savedInstanceState)
    }

    override fun provideNavigatorProvider(): NavigatorProvider {
        return DemoNavigatorProvider
    }

    override fun provideRootView(): ViewGroup {
        return rootView
    }
}

I'll see and find if there's a 'proper' fix for this, or if something like this will be included in AcornAppCompatActivity.

from acorn.

gumil avatar gumil commented on June 16, 2024

Thank you for further investigating this!

I think this workaround works. Seems also like an edge case since I am just experimenting on Acorn and programmatic views with Contour. I just have this idea that when Jetpack Compose is released, programmatic views will be more common.

from acorn.

nhaarman avatar nhaarman commented on June 16, 2024

Yeah it's a basic case that really should work though. Thanks again for the repro!

from acorn.

nhaarman avatar nhaarman commented on June 16, 2024

An investigative issue on the android tracker: https://issuetracker.google.com/issues/141726320

from acorn.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.