Office Hours Transcript: 2021-06-15

KaiH joined

hello, Kai!

Hi there

how can I help you today?

Why did you change chat clients?

 

And how are you?

OK, and I was concerned that Campfire might get shut down

I have a class that I want to unit test that uses Log.d(). Have you had that case and how do you solve it?

I tend to use Timber in production work

 

Robolectric might handle Log calls

I used Robolectric some time ago but disliked it for some reason I don’t remember right now.

 

Timber might be something. How can that be used for better testing?

 

(ofc it’s a Jake Wharton thing X) )

AFAICT, Timber recognizes when it is not in an Android runtime and just routes messages to System (e.g., System.err)

Ivano_ndrocchietto joined

hello, Ivano!

Good morning Mark!

Kai: you can also use libraries like https://github.com/LachlanMcKee/timber-junit-rule to control how Timber logging works in a JUnit test

 

Kai: let me take a question from Ivano, and I will be back with you shortly

 

Ivano: your turn! how can I help you today?

I started a new job as consultant, and using a completely different stack, have some curiosity, but first thing first, I have a problem with a View and would like to know what I do wrong

 

Basically I have a View on top of layout, I need to use this view only the first time and basically what i need to do is to dismiss it if user tap outside this view, namely on the screen externally to this view, I am into a fragment, and cannot use DialogFragment because need to use some references to guideline

 

I tried to make the view visible like this

 

val popUpMessage = findViewById<View>(R.id.fragment_home_first_time_pop_up)
val coverView = rootView.findViewById<View>(R.id.cover_view)
val trianglePopUp = rootView.findViewById<AppCompatImageView>(R.id.fragment_home_first_time_triangle_pop_up)

    coverView.visibility =View.VISIBLE
    popUpMessage.visibility =View.VISIBLE
    trianglePopUp.visibility =View.VISIBLE

    coverView.setOnClickListener {
        popUpMessage.visibility =View.GONE
        trianglePopUp.visibility =View.GONE
    }
 

basically I use a cover view that is transparent inside my constraint layout and then

 
    <View
        android:id="@+id/cover_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#00000000"
        android:clickable="true"
        android:visibility="gone" />
 

and with onCLickListener or onTouchListener I try to dismiss inside the lambda, but it works only if i tap more than one time

 

how can manage that a View in a fragment is cancelled if user touch outside this view

 

?

 

(sorry for the long question)

generally, what you have sounds fine

I cannot really debug this sort of problem in a chat client – this is the sort of thing that I would need to be able to run and debug

ok never mind

you could use Layout Inspector or something to try to see if something else is intercepting that first touch event

mmh good idea, I did not use

let me take another question from Kai, and I will swing back to you a bit later

 

Kai: over to you! do you have another question?

@Kai: your turn! do you have another question?

(btw i am not senior to work as (independent)consultant, just I am working in a company that do a lot of app, so I feel like that)

@Kai: if you come up with another question, chime in!

 

in the meantime… @Ivano: back to yoU!

 

I used to work with synthetics(i know is deprecated) in my old company, basically i write an id in the layout and I am good to go calling_text.setOnCLickListener for example no need to do any viewfindbyID

Ivano_ndrocchietto left

 

Ivano_ndrocchietto joined

but in this new projects they use a lot of references as ``` val homePageBanner = rootView.findViewById<CarouselView>(R.id.fragment_home_carousel_view)

 

otherwise i get a null pointer exception, how is possible that I use synthetics and get every sort of NPO if I do not bind the view to the id?

 

NPE*

synthetics assume that you inflated the right thing

 

it is very easy to refer to a synthetic for a layout that you did not inflate

ah I see maybe is because i use a lot of <include

my primary client’s project used synthetics, and we are in the process of ripping those out and switching to view binding

yes my senior asked me also

Why do you replace them? Is it a refactoring thing?

partly, synthetics have been deprecated by JetBrains

 

partly, we were running into a variety of bugs coming from our use of synthetics

But that ain’t reason enough for a lot of companies, as it costs money to refactor without any visible benefit for the customer.

it’s a reason if JetBrains stops publishing updates to plugins that support synthetics, causing problems when we try to advance the app in other areas

Ok

with framework deprecations, the deprecation is just a suggestion

 

with library and plugin deprecations, the deprecated stuff might get pulled in the future

 

a similar example is ViewPager, which is all but deprecated, since both FragmentPagerAdapter and FragmentStatePagerAdapter are deprecated

 

technically, you do not need to switch to anything else

 

from a practical standpoint, though, you may run into problems with future updates to other artifacts

 

at least, if the viewpager artifact eventually stops receiving its own updates

I see

as I wrote yesterday on this topic, "So, we don’t have to race and replace ViewPager this week, but I would recommend it sometime in the next year or two."

I would like to pose another small theoretical question

OK (and Kai, if you have a question, let me know!)

in my new job inside the fragments(we use single activity) in the onActivityOnCreated is everywhere rootView.findViewById<>()

 

I have never used a rootView and do not get from the internet

 

is something to refer to the activity beyond the fragment?

 

I noticed that the app works both if I do findViewById than rootView.findViewByid

 
     * <p>Finds the topmost view in the current view hierarchy.</p>
     *
     * @return the topmost view containing this view
     */
    public View getRootView() {
        if (mAttachInfo != null) {
            final View v = mAttachInfo.mRootView;
            if (v != null) {
                return v;
            }
        }

        View parent = this;

        while (parent.mParent != null && parent.mParent instanceof View) {
            parent = (View) parent.mParent;
        }

        return parent;
    }

where did you copy that code from? the androidx edition of Fragment has getView(): https://developer.android.com/reference/kotlin/androidx/fragment/app/Fragment.html#getview

I did control +B inside my app

 

is View.java

 

line 24670

 

amen

 

but unless rootView is coming from synthetics, I do not see how you can refer to that in a fragment

 

regardless, I cannot readily explain why your project is referencing it

is not coming from synthetics

 

is through this ``` var sampleImages = intArrayOf(R.drawable.temp_banner, R.drawable.ic_vomar_logo, R.drawable.temp_banner, R.drawable.temp_banner, R.drawable.ic_more)

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_home, container, false).apply {
   //TODO IVO make better
    val homePageBanner = rootView.findViewById<CarouselView>(R.id.fragment_home_carousel_view)
    homePageBanner.setImageListener { position, imageView ->
    }

TODO IVO make better :D :)

ah, it’s the apply()

 

this in the context of that lambda expression is the inflated View

 

and using rootView here would allow the fragment to reach out and manipulate widgets that are not from the fragment itself

 

that is not a good idea

I used OkHttp recently to call a web page with post multiform data and wondered if there is a good way to wrap it. Or if I should have used something else :)

I am uncertain what you mean by "wrap it"

 

for REST-style Web services, I tend to use Retrofit, which one could argue "wraps" OkHttp

I used it at a couple of places, but because of multiform data it got a bit longer, so I wanted to "wrap" it.

 

In another function or similar.

ops sorry

Ivano_ndrocchietto left

 

Ivano_ndrocchietto joined

sorry was called by the colleagues

 

is an hectic job

 

but is improving me a lot

Kai: OK, you should be able to do that, so I suppose I do not understand the question

@mark I do not not see the stack trace of the chat

yes, the transcript that you see is only from when you joined the chat

(server was reconnected, thanks)

I’ll be posting the full transcript to https://commonsware.com/office-hours/ shortly after the chat ends

thank you very much and sorry if i was not focused today, but super busy @moment

OK, that is a wrap for today’s chat

 

the next one is Thursday in the 7:30pm US Eastern time slot

 

have a pleasant day!

Same