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?
(OK)
@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!
thanks
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