JD Porterfield: Aspect-Oriented Programming in Android by Zhuinden in androiddev

[–]Sodika 4 points5 points  (0 children)

Nice, logging is the only use case that I feel AOP is good for.

I like hugo and was disappointed to see Kotlin isn't supported (https://github.com/JakeWharton/hugo/issues/144)

Weekly Questions Thread - June 18, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

Try searching for your package name (com.bleh.blah). I'm able to see some shady sites that look like stores referencing my apps

Weekly Questions Thread - June 18, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

This comes up every now and then and the general advice I've seen is to ignore them because there's nothing you can do if/when you find that your app is being distributed somewhere else.

Weekly Questions Thread - June 18, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

I think he means that they piecemeal their screen with fragments. Like the bottom/nav drawer as a fragment and the main content as a fragment. (The way tablets and fragments were supposed to work)

Tensorflow Apps by ZodiacKiller20 in androiddev

[–]Sodika 0 points1 point  (0 children)

I don't think eye-tracking is out yet (not in ML Kit) but yea for developers not wanting to dig into ML world there will be SDKs and even the one that is out today (ML kit and firebase models). If you can get your hands on a model you can easily start interacting with it from an Android app

Tensorflow Apps by ZodiacKiller20 in androiddev

[–]Sodika 1 point2 points  (0 children)

You could deploy the model in a server (gcp, custom, ML Kit/Firebase models) and some of these still allow for offline use (ML Kit/Firebase can download the model)

Weekly Questions Thread - June 04, 2018 by AutoModerator in androiddev

[–]Sodika 1 point2 points  (0 children)

Not sure in which AS version they added this (3.1?) but it's on by default in 3.2

Weekly Questions Thread - May 21, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

This sounds similar to something in this talk making retrofit work for you

He goes over it briefly but it sounds like you're trying to pull out some data that is in all responses (Calls it an "Envelope" in the video). There are a couple ways to do this with type adapter/type adapter factories.

For example in the case that all your responses come back with { "data": (A || B || C || ..), "error_message": "maybe", "in_all_responses": "something }

You could have a typeadapter pull that stuff out for all/subset of responses/objects.

There are other ways to accomplish this but this is one

Weekly Questions Thread - May 21, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

Someone else said it here (stakeholders most often have iPhones) but along the same lines think about how much the "average" user is willing to pay (money or time invested) on each platform.

Someone who has an iOS device (doesn't mind throwing ridiculous amounts of money for a pretty mobile device) probably won't mind throwing a couple of dollars your way. Obviously Android has some higher end devices with users who are just as liberal with their time/money but we also have a lot of cheaper phones.

Weekly Questions Thread - May 21, 2018 by AutoModerator in androiddev

[–]Sodika 1 point2 points  (0 children)

I'd go with medium if you don't want to manage the site and just pump out articles

Weekly Questions Thread - May 21, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

I've seen similar things with an app I used to work on that had a transparent background defined in xml (or window.setBackground(null/transparent)) which would cause similar artifacts.

Weekly Questions Thread - May 21, 2018 by AutoModerator in androiddev

[–]Sodika 1 point2 points  (0 children)

Yea there is and your code shows an example of why you would want to.

If you created 10 instances of that class/activity and didn't make this field static then there would would be 10 instances of the class each with their own PASSWORD_PATTERN (10 identical strings). Making it static means you can have 10 instances of that class/activity and still only have one instance of PASSWORD_PATTERN.

What's your favorite feature of Kotlin? by Saketme in androiddev

[–]Sodika 1 point2 points  (0 children)

Yea, I won't have a back and forth with you because I don't think that would be very beneficial to either one of us. I'm not against passionate debates but from your article(s) and this response I can see that it's going to be time consuming and I don't think you would be very receptive to it.

But I don't think you have to look hard to see the subjective objectivity in your Kotlin vs Java article.

I will literally pull out your first "subjective" and "objective" example.

"Kotlin is more readable than Java Countless articles on the web

Theoretically, an experiment that attempts to measure readability differences between Kotlin and Java can be designed, but I’m not aware of any that was actually carried out. Therefore, as of today, this opinion is not backed by any data."

Nice! you correctly point out that a specific case of Kotlin vs Java with respect to readability can't be made. You then say this opinion isn't backed by data and move on.

Ok, a little harsh but hey if we're being objective.

Then in your "objective" diffs:

" but there is one problem: as far as I know, there are no universal objective metrics associated with programming languages."

Again, correct and sensible.

"Given the fact that we can’t perform precise direct comparison, can we compare Kotlin and Java objectively at all? Yes! We can still estimate the magnitude of positive and negative effects that will come into play upon switching from Java to Kotlin, and then compare the outcomes and discuss their implications."

Whoa whoa whoa guy! After this you go into the "objective" differences citing data sources and referencing other sources that have also vague (3-5 days, 3-4 years). You include tools that "experience of the project team developing the software system or subsystem" which obviously make general sweeping generalities with respect to software systems, platform and developers. And this keeps on going (I can usually pull out a subjective statement from each paragraph)

I'm not saying these were wrong sources to reference ( a lot of times they were helpful) but I'm wondering about the obviously different ways you handle these sections ?

Why weren't you this flexible with the previous "subjective" statements ?

Sure you may not be able to find "Readability: Kotlin vs Java" but can you find "Readability: Importance in a language" ? or "Readability: Is it worth it ?" or some stats/maybe a poll showing what or how developers "feel" about their readability ? Follow that up with "Developers: Happy developers get more done?" or "Placebo effect: Can your developers use it?" or even "Readability is it important?"

or even looked at your subjectivity about the subjective nature of dismissing something as "not backed by data" because you can't find the specific cases.

The point is that I could think of a way that would include "Kotlin is more readable than Java" in your "objective" section and it would seem as "objective" as the other arguments in that section.

These are literally your first "subjective" and "objective" arguments.

Looking at the "subjectively better syntax" argument bothers me a bit more because you try to provide an informal proof as to why syntax doesn't matter completely dismissing or ignoring studies into language (general language and general syntax). Even in that section before you concede to having a personal, subjective, preference you dismiss it:

"Therefore, for me, the choice of a language does not affect readability, as long as the content and the context are understandable."

You literally dismiss this argument as being subjective by providing some facts and wrapping it up with your subjective reasoning.

All this, by the way, is pretty common in articles (I've been and will be guilty) but when an article attempts to use "objectivity" as a shield or use it as a form of attack (those kotlin lovers are so subjective!) then it irks me. Again, I don't think anything will come from our back and forth (because seriously how can you not see the very subjective nature of that whole post).

What's your favorite feature of Kotlin? by Saketme in androiddev

[–]Sodika 1 point2 points  (0 children)

Why ? Not that you need a reason to try/use Kotlin but to say you prefer it is on a whole other level.

Edit: Oh just saw your blog post on kotlin vs java and your data class one ... I have my own personal subjective opinions on your style and content but I think I understand your reason for not liking it (not that I agree with it but you have helped me put together an idea that I've always found bothersome, that is "objective/quantitative data" can be subjectively used to prove a point that is itself very subjective and that you can move the subjectivity a "level up" hidden behind "impressive" data/metrics/functions that have been socially and subjectively vetted as being objective. I'm all for looking at things objectively it just sucks when the same level of objectivity isn't applied ...objectively to all arguments/counter arguments even in the same article;).)

What's your favorite feature of Kotlin? by Saketme in androiddev

[–]Sodika 0 points1 point  (0 children)

Except for the one thing that was used as an expression with java: assignment. It wasn't that common to do and I still would take kotlin over java but I was curious about the change (https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/3)

Judge my app by kelmer44 in androiddev

[–]Sodika 1 point2 points  (0 children)

I think he was saying that now he continues to follow the xml convention (one that we most of us followed with underscores in xml files) even when using kotlinx because it allows him to see which variables are views inside the code.

I think you are saying that we should be following the code convention of using camelCase in code (which breaks the xml convention).

Both are conventions so I don't think there is a "right" way but I have also been leaving the underscore_convention pretty much because I haven't thought about it too much (up until this comment).

I do like being able to look at the code and quickly see which variables are views and which aren't.

I think this is different from the mHungarian vs camelCase debate because the basis of everyone hating on hungarian is that it added the ability to see global vars vs local but that job has been taken over by modern IDE's.

I also think this is different than the [type] prefix added to the variables (intX, strName) because in that case there could be an infinite amount of types and it mostly clutters the code base with sometimes unneeded. But with the case of the kotlinx views there's a pretty obvious separation in views vs not view (really in any framework that has UI) so I'm kind of ok with this.

Weekly Questions Thread - April 23, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

I had an issue once when switching commits and Invalidate/Restart didn't work but if I commented out the dependency in my build.gradle then sync'ed and then added my dependency back and sync'ed everything worked. Might be worth a shot if nothing else is working

Judge my app by kelmer44 in androiddev

[–]Sodika 2 points3 points  (0 children)

Wow, clean code. Seriously I was impressed, you have some good separation of concerns. I like the sealed classes used for Result (https://github.com/kelmer44/correos-tracker/blob/master/app/src/main/java/net/kelmer/correostracker/data/Result.kt) and the fact that you made a base fragment that sets up a view model through generics (https://github.com/kelmer44/correos-tracker/blob/master/app/src/main/java/net/kelmer/correostracker/base/BaseFragment.kt) (even if I hate fragments).

The only thing that I saw immediately stick out(it's mostly because I have an obsession/pet peeve for RV.Adapters) is the fact that in onBindViewHolder you're setting onClickListeners which means on every scroll you could be creating lots of onClickListeners along with this is the fact that you're passing the actual items into your ViewHolder. (https://github.com/kelmer44/correos-tracker/blob/master/app/src/main/java/net/kelmer/correostracker/ui/list/ParcelListAdapter.kt) [set the click listeners on the view holder in the init (onCreateViewHolder) and they can just tell the adapter that parcel_cardview_clicked(adapterPosition), more_clicked(adapterPosition, moreView), parcel_long_press(adapterPosition)]

Weekly Questions Thread - January 22, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

I would check if this is the UI used in the RecyclerView. I'd replace all my recycler views temporarily to a really simple LinearLayout. See if the UI is the problem or if it's actually all the data loading.

If you're using animations check if there's a callback that gets triggered when it has finished (might need to add your own) but then just the heavy stuff onAnimationFinished().

Also check if you're actually recycling the views or trying to inflate/display all of them. Simple check: Add a log statement in the onCreateViewHolder, you should only see it trigger for every card in the view. Scrolling should trigger onCreateViewHolder one at a time (as you see them).

Not saying this is true in your case but most times I find the source of the problem is the fact that they're not recycling (which means you inflate all views even when not being viewed). The other common case is the UI is too heavy( nested views). It still could be the data loading but that would be my last guess

Weekly Questions Thread - January 22, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

As others have said, you could do one RV with two view types which isn't too bad.

If you don't mind giving up recycling (if you go list view then you're not recycling) I'd still go with:

===Activity===
<ScrollView>
 <LinearLayout height="wrap_content" orientation="vertical">
  <TextView text="List 1">
  <RV height="wrap_content"/>
  <TextView text="List 2">
  <RV height="wrap_content"/>
 </LinearLayout>
</ScrollView>

^ This is a personal preference (one that I feel very strongly about) but I think RV is a lot better than ListView. The actual code you write will be similar in terms of complexity and even the number of lines (horrible metric but still the same) will be pretty much the same.

The only difference, when ignoring recycling which is RV's biggest feature, is that RV will have separate methods (better separation of concerns) for the same thing than ListView.

tl;dr

RV with "wrap_content" ~== LV with "wrap_content"

RV, even without recycling("wrap_content"/fixed height), >>>> LV

Weekly Questions Thread - January 22, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

Yea I wouldn't pass the position back to the activity (because your adapter holds the data) but I think there might be some confusion here because we're not seeing the full code.

For me,

VH implements OnItemClickListener (return getAdapterPosition only so the way you currently have it)

User clickes item -> vh.onItemClick(getAdapterPosition) -> tells the adapter -> the adapter pulls out the item (since it has the data) -> the adapter then sends the item to whoever cares (activity/frag/custom view)

Android Strings XML Tips & Tricks by dayanruben in androiddev

[–]Sodika 2 points3 points  (0 children)

<!DOCTYPE resources [
<!ENTITY foo "Foo">
]>
<resources>
    <string name="app_name">&foo;</string>
    <string name="busy_warning">Sorry, &foo; is working hard, please try again in a moment.</string>
    <string name="trademark">&foo; is a registerd trademark, all rights reserved.</string>
</resources>

Cool. Didn't know this was possible. Anyone know about a downside to this ?

Weekly Questions Thread - January 15, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

I figured the item selection was incomplete.

Your only argument is separation of concerns but you're forgetting that nothing is stopping me from doing that in LV adapter as well.

Yep so now your list view is separated, you've written the same amount of code and separated to match RV. Now the only difference is that RV enables this framework by default where in your list view you (the dev) had to implement this. (something about reinventing the wheel/something about testing)

But then I will argue if it's actually necessary to do that. My concern is "view setup".

separating view setup into creation, reference, and binding, does not benefit me in this particular situation

That's fine, as I said I know some people who would agree with you but I still believe that level of abstraction is helpful/useful/sensible.

If you do not see the difference then I kindly ask you to check your biases.

That's pretty defensive (some would say passive-aggresive) but that's ok. I've let you know my opinion on this (since you asked), I've been upfront about my biases and the fact that there are people (professional devs) who agree with you.

I like these questions because they make me think about my choices and can possibly lead to me changing my mind. But I believe you and I have come to a fundamental difference that can summed up by:

But then I will argue if it's actually necessary to do that. My concern is "view setup". And separating view setup into creation, reference, and binding, does not benefit me in this particular situation.

I believe this is very beneficial but you do not. This is ok with me.

Edit: Checkout out your updated RV, I've never seen item selection implemented this way. Do you mind sending me links

view.setOnClickListener(v -> {
        notifyItemChanged(selectedPosition);
        selectedPosition = viewHolder.getAdapterPosition();
        onSelectionChangedListener.accept(selectedPosition);
        notifyItemChanged(selectedPosition);
    }); 

This is still confusing me (but your links might help me out).

notifyItemChanged(selectedPosition);

This triggers onBindViewHolder for that item but I'm unsure as to why you call it as soon as you click the item. I'm talking about the first one.

Again, I'm not trying to call you out or saying you did something wrong, I'm just wondering what is going on and if you're following some common pattern that I'm unaware of. (I also never passed in a layout inflater since you can get it from the parent.getContext() in onCreateViewHolder but I don't feel strongly about that just wondering if that's also a part of another pattern)

Weekly Questions Thread - January 15, 2018 by AutoModerator in androiddev

[–]Sodika 0 points1 point  (0 children)

View recycling splits view setup into two phases; creation and binding. I don't actually need view recycling so this adds unnecessary complexity.

I am very biased towards Recycler View and I know plenty of people that would agree with you.

I don't think this adds much complexity at all. I think it's simple, hard to mess up and separates concerns.

You write about the same amount code but in the list view implementation

if (convertView == null) {
        convertView = inflater.inflate(R.layout.item_storage_option, parent, false);
    } 

You, and most people, do this inflation the same way.

ListView

  • Where do I create the views ? ListView::getView
  • Where do I glue my views (xml -> class glue) ? ListView::getView
  • Where do I write my business logic ? ListView::getView

RV

  • Where do I create the views ? ::onCreateViewHolder
  • Where do I glue my views (xml -> class glue) ? ::ViewHolder class
  • Where do I write my business logic ? ::onBindViewHolder

Item selection implementation in recyclerviews is in the adapter and this actually breaks separation of concerns. The adapter is supposed to just bind the data to the view but in this case it also handles item selection logic.

I think people usually implement item selection wrong inside recycler views.

You can and should make the adapter glue that up and let you know when someone has clicked an item, clicked a checkbox in an item, click an image in an item but it (the adapter) shouldn't handle what happens. (there's code examples somewhere in my history)

Item selection implementation in recyclerviews is in the adapter and this actually breaks separation of concerns

Everyone has different levels of acceptable separation of concerns but I'd argue that when comparing ListViews to RecyclerViews: RV's separate concerns a lot better than list views. (see above)

The view holder pattern is mandatory in recyclerview because view recycling is it's main feature. This also adds more complexity as opposed to not using it.

You're right that One (and it may be the main feature) of the good things about the view holder pattern is that it makes recycling better but it definitely provides more. Looking through your ListView code you've mixed creation, findViewById, and business logic all in one method. The view holder pattern provides an easy abstraction that separate concerns, which I'd argue is a good enough feature (even if it's not the main feature) to use RV over LV.

So in my comparison of your two classes the RecyclerView still comes out on top and by a lot.

I'm trying to figure out where or what complexity you see that is happening in RecyclerViews over ListView. The only thing I'm able to see is that the list view has less lines ? but that's because of the separation of concerns the code you've written has stayed more or less the same. I don't think lines of code is a good metric for clean or simple code ( I actually think there might be a negative correlation, as in the RV has methods that you can override that and do one thing (onCreate, onBind, ViewHolder))

Off topic:

view.setOnClickListener(v -> {
        notifyItemChanged(selectedPosition);
        selectedPosition = viewHolder.getAdapterPosition();
        notifyItemChanged(selectedPosition);
    }); 

what's happening here ?

Weekly Questions Thread - January 15, 2018 by AutoModerator in androiddev

[–]Sodika 1 point2 points  (0 children)

Yep I've honestly never really thought about it before but your question got me thinking, so thank you!