Android Testing: What do to when nothing has an id? - java

I'm trying to write some automation scripts for an app I have. I've done the tutorial on Robotium's site and have a basic understanding on how I can automation. However from what I can tell regarding the app I'm testing is by using the android hierarchy viewer I see that all of the views have no ids that were explicitly defined.
As you can see from the screen capture there are views upon nested views. The IDs for them read like 0x17e0 or 0x17de. How can I reference these, specifically, in a robotium script? The end result is I'm trying to get it to fire a click even on one of the Text Switcher views. So far I've only been able to make it work if I give it a pixel point to go to, or if I give it the text that appears in the button (but the text is dynamic and would make for a poor test).
Do I have to use the getCurrentViews() to filter down to the text switchers? Or do I have to figure out a way to traverse the entire tree going from FrameLayout>RelativeLayout>FrameLayout>LinearLayout>TextSwitcher ?
If I have to traverse the entire tree how do I get view upon view upon view?

While I couldn't get the ViewGroup() and getChildAt() methods to work for me I ended up doing something different:
// Grabbing all the LinearLayout views found under view with with id of 'content'
ArrayList<LinearLayout> linearLayouts = solo.getCurrentViews(LinearLayout.class, solo.getView(R.id.content));
// The 4th item in the linearLayouts list is the one I need
View pickerList = linearLayouts.get(3);
// Grabbing the buttons in the pickerList
ArrayList<TextSwitcher> buttons = solo.getCurrentViews(TextSwitcher.class,pickerList);
// Now I can click on the buttons
solo.clickOnView(buttons.get(0));
I will say this is slow. It takes about 10 seconds for the first button click to fire. But once it goes it flys.

I would vote to say you really probably want to get some IDs added somehwere in the hierarchy, it is a one line change that will make your life a hell of a lot easier.
But i am not without help if for some reason you cannot get this done, to do this you are going to have to walk the entire to get to the view you want.
Getting the top level view, you will be able to cast it into a ViewGroup. ViewGroups have a method called getChildAt() which you can then use to get a child at a given index, the index is 0 based and will match what you see in the hierarchy viewer so you can chain together theses commands to get to the view you want to interact with.

I have not used Robodtium very much, but i know that AndroidViewClient does exactly what you want. Here is a code snippet that dumps Id of the home view:
ViewClient(*ViewClient.connectToDeviceOrExit()).traverse(transform=ViewClient.TRAVERSE_CIT)
Here is the result dump:
com.android.launcher2.CellLayout id/cell3 None
com.android.launcher2.ShortcutAndWidgetContainer NO_ID None
com.android.launcher2.BubbleTextView NO_ID Email
com.android.launcher2.LauncherAppWidgetHostView NO_ID None
android.widget.AnalogClock id/0x7f0f0014 None
com.android.launcher2.BubbleTextView NO_ID Camera
com.android.launcher2.BubbleTextView NO_ID Settings
com.android.launcher2.BubbleTextView NO_ID Gallery
com.android.launcher2.LauncherAppWidgetHostView NO_ID None
android.widget.LinearLayout id/0x7f080167 None

Related

"Fold-out" for row in RecyclerView

Java 8, min SDK: 24, target SDK: 27
My app displays a map with some type of map marker (within a Fragment) and if I click on one of these markers, a popup comes up to show some additional information about this marker. Currently I'm using a normal AlertDialog for that but I might replace it with a DialogFragment in the future.
Inside the dialog there's a RecyclerView that is filled with multiple values. If I click on one of the rows, I want my app to open a "fold-out" underneath it (the other rows should move down) that displays even more information about that row. Clicking on the row again should close that "fold-out".
Similar to what the FoldingCell library does but I want to add to the original row (instead of replacing it) and also don't need the fancy animation.
Like this:
Is "fold-out" the right word for it? I'm pretty sure I saw a similar question here on Stackoverflow (might have been for iOS) a while back but I've not been able to find it again yet. I know how to do the whole onClick thing for the map and the RecyclerView but how do I accomplish the "fold-out" part (create design in xml, then load via Java class)?

Ideas on how to set a button to call a specific position from an ArrayList in a separate activity

Long post ahead...
Ok, I'm not sure how to explain it so I made a couple of screenshots. Also, I want to start off by saying I'm not looking for somebody to write code for me to copy, or links to specific articles. I just need help figuring out if what I want to make is possible and any direction on what to look at. I just haven't done something like that and so far I can't seem to word my searches well enough it seems to be able to find a solution.
TL;DR: I need to get scrn2 to either swipe left and right to prev/next card from the RecyclerView, or add buttons that do that
So. Here's the screenshot. I have already made scrn1 and scrn2, and am looking for a way to get to my mockup (that heart button there is just wishful thinking and I'm not at all concentrating on it, and the buttons on top of the cards are just a left-over from an old test I forgot to remove).
The idea behind this is just sort of a catalogue/text book to help with self-preparation for an exam on a specific topic.
What I have is a RecyclerView that I've populated with CardViews in an ArrayList. Since I'll be having a few cathegories of cards, and each will have around 40-50 in there, this seems like an efficient and quick way to load a long list like that, and it runs smoothly so far so I'm happy with it.
In order to get a "full details" screen (scrn 2) I implemented Parcelable to my single item template/class, and now when I click on a card I get that second activity that shows the full sized image, title and full description text.
I also added a search that filters the cards in real time, since there will be many of them and I want it to be easy to get to a specific item.
So far so good. Everything works, surprisingly.
Where I'm stuck now is that it will be extremely annoying for somebody to keep going in and out of the single items in order to get to the next one, so I need to be able to either make them scroll or have buttons at the bottom that go to previous and next. The thing is, the only time I've used swiping is in a tabbed activity and that requires fragments. When making those I had to have an xml for each tab, and a class to correspond to it, which is definitely not comfortable when I have 40 in 10 categories.
I assume I need something like an onClick event to add for buttons in the activity that holds the information that gets acquired from the RecyclerView to bring a specific position from my ArrayList... Like, if somebody clicks on the third card, the button brings -1 or +1. Or something like that?
Makes some sense in my head, but I can't find a way to search for that, and can't figure out if it's even possible to make. Soo any pointers would be hella useful. I'm really excited about being able to do that much from scratch, but still lack too much knowledge to be able to imagine what would work here. I'm still testing things out and am looking around for information, but will be happy if somebody has input on the situation.

How to check if a View reach the end of ViewGroup

I have been working on an app that adds views programmatically to a linear layout.
The problem is if I add too many views it will go off the screen.
I would like to know how to check if a certain child has hit the end of the same view group so I could add it into another layout (a linear layout below the first one) before it "flows" and go off the screen. How might I accomplish this?
Rather than reinvent the wheel yourself, I suggest that you check out the FlexboxLayout project by Google: https://github.com/google/flexbox-layout
A FlexboxLayout will automatically give you the behavior you're describing, plus the potential for much more.
Well, there are a good number of ways you could implement this in android other than going through this hustle. What ever you are trying to do at the moment may fall under one of the following cases.
Creating views programmatically most likely means you have a dynamic data set probably from an external source.
Your dataset is limited or static but just more than the average screen can display.
if any of the above apple then you are better off using a ListView or RecyclerView (Recommended). That way your data is full displayed as a scroll-able list and you don't have to worry about some items or views not showing or going of the screen. This can range from simple string list to complex nested views.
This will be very efficient as it will automatically handle optimization and usage of memory as well as performance.

How does the search view even get rendered?

I have been digging around in the search view source code for quite sometime now trying to understand how exactly does the search view even have a user interface to be rendered. First of all here is the source code:
SearchView source code
So what I don't understand is how does the user interface element of the search view even get rendered when the search view doesn't even have any onDraw() method. All that I can see is responsible for the display element is a bunch of view at the start which are in the constructor, the SearchView gets a reference to and change the background and set the image of these view. If all that I can see was done is getting references to some views and changing the background as well as the image without having it within the proper view hierarchy then how exactly does it even get rendered?
I understand what you are probably wondering why do I even need to understand this. Well I want to understand this so I can create my own custom search view. Since I only need like 2 function on my search view I figure it would be a lot better to make one that suits my need instead of the thousand of lines of code in the source one. Plus, I want to create one that I know I will understand how to use not the complex default one.

SMS Balloons / Long Chat Boxes

I want to be able to add a text-messaging balloon every time the user revives data from a HttpGet, I want it so that it looks nearly identical to the default Android text messaging UI. I'm fine with all the code, I just need a way to create the UI and create another text balloon every time data comes back from a HttpGet request.
Thanks ever so much, for the answering this questions and I'm sure there's an easy way to do it, yet I've found no way by using the 'ole Google.
I am doing something similar for my app am doing the following to achieve it:
You will need a 9-Patch-Image (a stretchable PNG, see here) that represents the bubble. You want to make the part stretchable that does not include the corners of the bubble. You can create the bubbles using an image editor of your choice (I'd recommend a vector graphics editor like Inkscape). Then use the 9-Patch editor included in the Android Developer Tools to transform the PNG image into a 9-Patch PNG.
Create a custom layout file for one bubble. Create a textview inside it, and add your bubble as a background resource. (android:background)
Use an arraylist with a custom adapter to inflate and fill your items.
So far, this will give you identical bubbles as background for all messages.
If you want to get fancy, you can create different bubbles for participants, and use the setBackgroundResource method in your Adapter to set the correct background.
Further, if you wish to align them left or right, like in the message app, you will need to add spacers to the left and right of your TextView in the layout file. I used FrameLayouts with a fixed width. Make sure to set their visibility to GONE.
As with swapping the different bubble colors, just set the visibility of the left/right spacer.

Categories

Resources