FindViewById and multiple layouts for different screen densities (Android) - java

my question has to do with using different layouts for different screen densities on the Android platform.
Let's say that I have four main.xml files (each in their respective folders for their corresponding screen densities: ldpi, mdpi, hdpi, and xhdpi) and let's say that they're all identical to start with. But let's say I want to get rid of some of the UI elements for the ldpi layout. How do I handle things on the Java side to avoid a null pointer exception when it tries to find that view in the ldpi layout on a ldpi phone? Should I just check and see if findviewbyid returns null and move on from there?
I realize that you're supposed to keep things uniform in your apps, but on occasion it just seems like it'd make more sense to just get rid of a convenient but otherwise unnecessary UI element. I love having the extra real-estate on these new phones, but if/when it comes time to make a ldpi layout, I'd rather not just cram everything in there when it'd look better just to get rid of some stuff, if that makes any sense!

It is a Good question. Null checking can be one of the solutions.
another solution is checking screen properties. look at this example:
public static boolean isTabletPC(Context context) {
boolean isHoneycomb = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
boolean hasLargeScreen = (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
return isHoneycomb & hasLargeScreen;
}

This is handled the same way as handling any optional element. Check if it exists (not null) and handle accordingly. In case of a non-existent View, findViewById will return null and you can operate further on the View inside a if(null != view){} block or if there are multiple optional elements that can be grouped, you can use an instance variable.
HoneycombGallery demo gives an idea of how you can detect device properties using layouts (although in the demo, it is done for fragments, it can be applied for any View)

From api lvl 11 you would probably want to use fragments for that. This way your java code always deals with views that are definately there, and your layout can show (or not) certain fragments that take care of their own business.
I would advice against littering your code with checks for what kind of screen you have, and checking if a certain view might be in the screen.
If you look at figure one on the linked page, you see a clear example of what i mean:

Related

can I create many different indexed ImageViews using the same background? (android)

I'm making some sort of orb-dodging game and I want to create many different orbs. usually, to create an Image\button\whatever I make a single thing in the XML and assign it to an object on the java code. it does work well when there are a few objects but can I make an essentially unlimited amount of orbs using a single picture?
XML was introduced at the beginning of Android for "easier" layouting (it turned out it wasn't so much, got own problems, currently new approaches are more popular), but all of its possibilities can be achieved with code. e.g. creation of new TextView instead of findViewById form XML: textView = new TextView(this); (this for Activity, if you are in Fragment just use requireContext() instead)
remember that Views created this way won't appear on the screen, they must be added to Activitys/Fragments layout (using setContentView or onCreateView respectively)
btw. making a game using "unlimited amount" of Android framework Views is a very bad idea, you will get VERY poor performance... at least use Canvas drawing

RecyclerView with swipe action menu

I have a RecyclerView with the implementation of ItemTouchHelper. I am dragging and sorting the items in RecyclerView using ItemTouchHelper.
Also I am performing different actions on different direction of swipe. If user goes from left to right (Swipe) I just Deactivate status of item. If he perform right to left swipe I activate the relevant item.
What I want:
But now here comes the change, What I want is that I need to show some icons after I perform right or left swipe. And By clicking on those icons/buttons I want to perform action then.
Problem:
Problem is as I told you I have implementation of ItemTouchHelper, then how I am doing to perform what I wanted (as described above)
How to solve this? I have seen many libraries but they have limitations, also as the app has very much things going and there are some more implementations on RecyclerView used in our app, so I really do not want to risk the rest of implementations for the sake of this..
UPDATE 1:
To clear my question more I am going to add on more. Right now My implementation is something like this. But this is not what I want. I want to show swipe menu for any type of swipe I mean either it is left or right I want to show some icons on left and right side of item
You can take iOS swipe menu as an example (see here). I want exactly same behavior in android.
You're asking the impossible: suggest a library that doesn't exist (as you have already found out).
You're asking people to also find a solution for a problem you only briefly describe. You're not providing any code whatsoever, nor any specific issue you're facing when trying to come up with a solution; you're essentially expecting magic to happen.
How can you make this better?
Provide something like: "I'm attempting to implement a swipe solution for a recycler view's row; when I try to do YYYY is happening instead. Hhere's my piece of code where I do , calculated like this , am I missing something?"
Anyway...
You claim to be using an ItemTouchHelper already, so, if you look at how a very basic one works, you'll notice that the helper will ultimately draw on the canvas directly via:
#Override
public void onChildDraw(
final Canvas canvas,
final RecyclerView recyclerView,
final RecyclerView.ViewHolder viewHolder,
final float deltaX,
final float deltaY,
final int actionState,
final boolean isCurrentlyActive) {
This is derived from the platform ItemTouchHelper.SimpleCallback. So...
If you want to implement your solutions, you'll need to implement it there to do things like stop dragging, draw the content (icons), etc.
It's not a trivial solution and getting the whole thing right is difficult; more so if you introduce "some more implementations on RecyclerView".
I hope this answer points you in the right direction, and that your next related question is more about what you've tried (and failed) to do, than a "please do this for me" scenario. (If your intentions weren't those, please apologize, but you spent 5 minutes typing this question and it would take hours/days to implement this, so set your expectations this time).
Finally, when I wrote this, I realized most people wanted iOS swipe behavior; unfortunately, said behavior is not pre-implemented (like on iOS) on Android and you have to deal with it yourself; it's not impossible nor the most difficult task on earth to do on Android, but will give you a few headaches if you're hacking RecyclerView too much.
UPDATE
You've realized now, that ItemTouchHelper has a problem. It draws on the Canvas directly, so it has no knowledge of a Layout, View, Margin, etc. These are all things that live outside the realm of the touch helper. The helper is given a canvas, and drawing capabilities and that's it.
Where does this canvas size come from?
Well, it's calculated during the layout/measure pass(es) for the RecyclerView and its views.
How do I then stop dragging "at exactly the center of the screen" then?
Pass the values to your Helper; remember that the responsibility of calculating where the middle of the screen is, is not in the TouchHelper's contract; but your Activity/Fragment does know this. Provide the information the Touch Helper needs to perform the things you want it to perform.
Revert "back" to the original position, means knowledge of what the initial state was, etc. All this information is known by the RecyclerView and beyond, not the TouchHelper.
So you'd need to measure your layouts, save some values, pass them to the touchhelper so it can operate, etc.
As you can see, the full picture starts to become more and more complicated. My advice to you is:
Try to push this feature OUT as "the platform doesn't do it it will take time, it's not worth" (the worthiness and discoverability of swipe actions is dubious at best, but it's an ubiquitous action nowadays so you may have to do it regardless).
If you really have to do this, abstract things as much as you can, create all the classes/interfaces you think you can need, even if you end up with a "MiddleScreenCalculatorDelegate" kind of thing. It will be easier to fix later, but at least have each component do a very small subset of things.
Lastly, your item touch helper will have to calculate how much offset (delta) has the view been swiped already and stop when it reaches a known threshold.
Good luck :)
p.s.: I suggest you post a different question with specific issue(s) to get better help, this answer is very unhelpful as it is. :)

Android Best Practice: Dynamically adding buttons to a ViewPager or Pre-Instantiating Them?

So I have a question about best practice for dynamically creating and sizing buttons within a ViewPager, based on a changing external state.
Essentially, I have a scrolling view and I want my ViewPager to contain a number of buttons of a specific size and count depending on what part of the scrolling view is currently visible.
My question is about deciding the best implementation of this feature, I see two options: would it be simpler to
Constantly create and scale new buttons whenever the scrolling view moves
Make the viewpager itself contain a scrollview and fill it with all of the pre-scaled buttons on app startup. Then, whenever the user scrolls the main scrollview the viewpager's scrollview (which contains the buttons) will scale programatically
Any ideas on which would be the simpler and more robust system?
Not much of an answer but I will leave a comment for ya! Basically you can do it either way, both aren't to difficult to accomplish, however I would probably go the dynamic route because it will always scale correctly. Doing a set amount will only work until devices become larger, or if you are targeting tablets or tvs then it will start to become extremely messy in the xml file for the layout. Dynamically adding also gives you far more control and saves time later on, you can simply change a number and have 100 more then going through and manually adding even 10. Hope this helps!

Create a view class that is a combination of two views Android

In my app, I have a screen that displays some images next to text. These images are downloaded from the internet, so there will be some latency in displaying them. Right now I have an ImageView and a ProgressBar overlaying each other, and toggling the visibilities when the Bitmap becomes available. Is there any way to combine the two into one class that will handle it all in case I want to use this somewhere else?
One way to go about solving the problem is to make your own custom view which extends ProgressBar and draw the image in the ondraw(Canvasn canvas) using a Rect. That way, your image can be embedded in your view and you can always make it reusable by allowing your self to set the image via a setter/resource xml files which specify the attributes that go along with your custom view. Here's a reusable ProgressButton that I wrote that maybe of use to you, it shows how I did something similar to what I described (it's one which I think works well):
PregressButton
Yes there are a number of ways to combine widgets into a single custom class. Have a read of Custom Components. This should help you decide which approach you want to use for your situation.

Is it more efficient to declare a view invisible or set the background to transparent and change it's background resource when needed?

Trying to get the most of my app means making more efficient code to help the user have a better experience. So I was wandering if anyone could help me and let me know which is a better choice for efficiency.
I have views which come to life at various times in the program through animations but their places are still held in the main layout so the buttons are constantly in existence. I was trying to figure out whether it's more efficient to go ahead and set the background resources in the xml code and just set the visibility to invisible and then change it back to visible dynamically when the views are needed, or is better to set the background resource to transparent and change the background resource when needed dynamically?
I'm aware the difference is minimal but when trying to use an app the most frustrating thing can be speed so knocking off even a quarter of a second in loading time is a step towards more efficient and more complete experience for the user.
If you're concerned about having many views in your layout that are seldom used, check out the ViewStub class. It's basically a placeholder that you can use to lazy initialize views that might not always be required.

Categories