I recently made an update to the iOS version of an app I made and I want to put that same functionality into the Android version. Basically, it takes user input of a year, which they select from a list and then the year previous to that is entered into the placeholder text of text field I specify. When I looked up how to do the same functionality in Android, I found out I needed an OnItemSelectedListener. However, that is when trouble arises. After adding the necessary code, and importing AdapterView into my Activity, my app keeps crashing on first launch. Since I am not sure where it keeps crashing, here is a link to my app's github page
Github Experimental branch
The code on the master branch works fine, so this is really strange.
Since the files are hard to decipher, here is the code I used to apply the OnItemSelectedListener:
// give Spinner a listener for new functionality to work
selection.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView, int position, long id) {
// get year selection for use with new functionality
int iyear = Integer.parseInt(selection.getSelectedItem().toString());
balance.setHint(R.string.balance + " from 12/31/" + pyear.getPrevYear(iyear));
}
// create empty method
public void onNothingSelected(AdapterView<?> parentView) {}
});
Make sure the var balance is not null at the time of setHint. It could be that the id in findViewById is not right.
Make sure that R.id.amount is a view inside of R.layout.main.
I still don't see the LogCat which is the most vital piece of information when tracking down an error...
So these are my guesses:
I don't see where you define an adapter for selection so I assume that you do this in the XML. Have you confirmed that selection.getSelectedItem().toString() is a valid String for Integer.parseInt()?
If you have access to the array (call it selectionArray) you can simply use:
... + pyear.getPrevYear(selectionArray[position]);
R.string.balance is an integer that references the String that you want. To display the String itself you want to use getString(R.string.balance) or probably getResources().getString(R.string.balance).
Verify none of your variables are null: selection, balance, and pyear.
To explain the first point a little more:
Create a class variable for the array and the String:
int[] choicesArray;
Initialize it in onCreate();
choicesArray = getResources().getIntArray(R.array.choices_array);
In OnItemSelectedListener use:
balance.setHint(getResources().getString(R.string.balance) + " from 12/31/" + (choicesArray[position] - 1));
I went through and copied things from the master branch and things started working without crashing. Now, I am having issues with the hint, but since this question on why it kept crashing, I am not sure I can keep the question open.
Related
I've created an (empty until now) View in my Eclipse Plugin. I'm also using Eclipse Cloudio. This library provides the following object (description taken from the linked site):
A TagCloud is a special org.eclipse.swt.widgets.Canvas, dedicated to display a tag cloud.
Basically it's an image showing a WordCloud. Now there are snippets on the site on how to show such TagClouds in a shell / popup.
But I'd like to show them in a view (this function is supposed to be used often and I think it's bad style to spam popup-windows).
What I do not know tho is how to set this TagCloud (which is a Canvas) to the View / make the View display the Canvas. Maybe someone can help me with this?
Edit:
gregs Answer works like a charm! It just needs another setWords() function which is called from where-ever which contains .setWords to set the words when neccessary.
You just need to add the control to the view in the view createPartControl. At the simplest that would be:
#Override
public void createPartControl(final Composite parent)
{
TagCloud cloud = new TagCloud(parent, SWT.NONE);
... set up the cloud as in the example
}
Found the issue on my payment Input control. There was a small computed Text field that was failing but not throwing an error. Just stopped the whole process. In any case removed the computedText and it now works. The compositeData formula that returns pItem to the custom control still fires way to often but I can't figure out how to stop that. It is all memory resident so it is probably not a major performance hit, but still.....
This question is a follow up to my previous question and I will try to refine the issue
defining an object property in a compositeData on a custom control
Here is a picture of what I am trying to do:
The repeat control is bound to an arrayList generated by the Java method Payments.getAllItems(LinkKey) and that works correctly. The button in the repeat is fairly simple it just setts the viewScope.vsShowPayment = true and vsRIndex to the repeat Index value so I know which element in the ArrayList we are working with. It then does a refresh of the panelPaymentContainer which hides the repeat and renders the custom control ccTestPayment.
ccTestPayment has a custom property called pItem of the type java.lang.Object with this code:
<xc:ccTestPaymentInput rendered="#{javascript:(viewScope.vsShowPayment)}">
<xc:this.pItem><![CDATA[#{javascript:try{
var debug:Boolean = true;
if (debug) print("Open existing row = " + viewScope.vsRIndex)
rIndex = parseInt(viewScope.vsRIndex.toString());
if (debug) print("rIndex = " + rIndex);
pItem = Payments.getItem(rIndex);
return pItem;
}catch(e){
print("Failure in Custom Prop of add item " + e.toString());
return null;
}}]]></xc:this.pItem>
</xc:ccTestPaymentInput>
the method in the class Payments Payments.getItem(rIndex) then returns the PaymentItem Object from the ArrayList of PaymentItems and displays them in custom control. the fields in the custom control are bound to compositeData.pItem.getPaymentDate etc and to this point everything is cool.
I can edit any of the fields on the custom control and that all works fine. However, when I press the "Save" button none of the code in it gets executed.
try{
print("Start Payment save");
var debug:Boolean = true;
var pos:Integer = parseInt(viewScope.vsRIndex.toString());
if (debug) print("Working with pos = " + pos + " Call saveThisItem");
if (Payments.saveThisItem(compositeData.pItem , pos)){
if (debug) print("save Payments Worked ");
}else{
if (debug) print("save Payments FAILED ");
}
}catch(e){
print("payment save Error " + e.tostring);
}finally{
viewScope.vsExpPayDate = null;
viewScope.vsShowPayment = false;
viewScope.remove("vsRIndex");
viewScope.remove("vsGotItem")
}
None of the print statements get fired. I suspect it has something to do how pItem gets defined. the code behind the custom property gets fired over and over again and I'm wondering if that is getting in the way.
The reason that the save was not working was that there was a computed Text field on the control that generated an error. The problem was that there was no error message reported on the client nor the console. After a lot of head scratching I noticed the text filed was no longer displaying the value it was supposed to. Deleted the field and the save and everything else started to work.
On the issue of the number of times the processes are called I think I have resolved many of them. I'm moving the control ccTestPaymentInput.xsp inside the repeat. It will now have direct access to the 'current' PaymentItem Object so I can access teh repeat var=pItem which is teh PaymentItem object I want to work with. Clean and far simpler than what I was doing. The only refreshes necessary are the ones related to the rpeat control and there is not much that I can do about that.
I'm new to robotium and i'm trying to write a quick and dirty script to run through all screens in an app.
The problem i have mainly with the 'home button' in the app. I've tried lots of options but i cant seem to get it to click there except with index, which is not what i want.
When i check out the button with the hierarchyviewer it looks like this:
Link
However when i try for example:
assertTrue(
"Wait for text (id: myapp.R.id.home) failed.",
solo.waitForImageById("myapp.R.id.home", 20000));
solo.clickOnImage((ImageView) solo.findViewById("myapp.R.id.home"));
solo.waitForActivity("MenuActivity");
It fails at the waitForImageByID line. Ive tried multiple options like waitForImageButton etc, but i just cant seem to get it clicked. What am i missing here?
junit.framework.AssertionFailedError: View with id: '0' is not found!
at com.jayway.android.robotium.solo.Solo.getView(Solo.java:1990)
at com.jayway.android.robotium.solo.Solo.getView(Solo.java:1970)
at com.bitbar.recorder.extensions.OtherUtils.a(OtherUtils.java:246)
at com.bitbar.recorder.extensions.OtherUtils.b(OtherUtils.java:241)
at com.bitbar.recorder.extensions.v.a(Waiter.java:71)
at com.bitbar.recorder.extensions.ExtSolo.waitForImageButtonById(ExtSolo.java:4176)
at com.example.android.apis.test.Test.testRecorded(Test.java:137)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1740)
Use the following line to press the home button in the action bar
solo.clickOnActionBarHomeButton();
The issue is that the id that it is referring is not in your application, it is in androids default R file, try android.R.id.home and it should work fine. It is worth noting though that if your application uses action bar sherlock to support the action bar pre 4.0 that this will have a different ID there and you will have to handle this in your test.
You can see this for yourself looking at: http://developer.android.com/reference/android/R.id.html
When you are using ActionBarSherlock there are two different Ids you have to check, android.R.id.home for API-Level>11 and abs__home for lower levels (provided by ActionBarSherlock):
View homeButton = activity.findViewById(android.R.id.home);
if (homeButton == null) {
homeButton = activity.findViewById(R.id.abs__home);
}
What about this code:
ArrayList<LinearLayout> ll = solo.getCurrentViews(LinearLayout.class);
//You can change 1 with the ordinal number of LinearLayout you want to click.
solo.clickOnView(ll.get(1));
or also
ArrayList<ImageView> iv = solo.getCurrentViews(ImageView.class);
//You can change 0 with the ordinal number of Image you want to click.
solo.clickOnView(iv.get(0));
I think if you identify the correct id for view or linear layout or image view it should work.
Dave C's answer was working only partially for me. The button was clicked but before the preceding screen was loaded assertions had started and thus were always false. The solution is to run "home click" on the main thread (Robotium 5.2.1):
getInstrumentation().runOnMainSync(new Runnable() {
#Override
public void run() {
solo.clickOnActionBarHomeButton();
}
});
From your question I can see that it is an image view. You can click on any view using the following piece of code.
View view = solo.getView("View_name_from_hierachy_viewer");
solo.clickOnView(view);
View_name_from_hierachy_viewer in your case will be "home".
Let me know if this does not work.
I'm trying to send text to a view that I know the id of. It seems enterText() wants an int, but all I have is a view.
solo.enterText(solo.getView(R.id.et_firstname_insurance), firstName);
Ideas? I read the API documentation and can't figure it out.
I figured it out with the help of my coworker. This turns the view into an EditText object, which can be passed into one of the flavors of enterText:
public static EditText getEditText(int i) {
return (EditText) solo.getCurrentActivity().findViewById(i);
}
EditText eFn = RobotiumHelpers.getEditText(R.id.et_firstname_insurance);
solo.enterText(eFn, firstName);
I'm pretty sure that this is not allowed. Robotium is testing purposes and if you're changing the whole state of the activity externally than that defeats the purpose and might possibly have the ability to do damage. Now if you're talking about entering text in something that is editable than the int is the editable field number. Check out the tutorial
you can assign this to a view as view1 and then you can use
solo.enterText(view1, firstName);
and if that also doesn't work try using solo.clickOnView(view1);
and after that solo.enterText(view1, firstName);
What worked for me - assertTrue("btnUseEmailToLogin View is not visible", (solo.getView("idName") ).isShown() == true);
Where idName - is the id of desired view to check
I am taking my first steps with Apache Wicket and ran into the following problem. I have a ListView that displays a "delete" link right next to its entries. When the delete link is clicked, the entity represented by the list item is deleted from the database but the list itself does not get updated until I reload the page manually in the browser.
IModel<List<SampleEntity>> sampleEntityListModel = new LoadableDetachableModel<List<SampleEntity>>() {
#Override
protected List<SampleEntity> load() {
return mSampleEntityBA.findAll();
}
};
mListview = new ListView<SampleEntity>("listview", sampleEntityListModel) {
#Override
protected void populateItem(final ListItem<SampleEntity> item) {
item.add(new Label("listlabel", new PropertyModel<String>(item.getModelObject(),
"text")));
item.add(new Link<SampleEntity>("deleteLink", item.getModel()) {
#Override
public void onClick() {
mSampleEntityBA.delete(item.getModelObject());
}
});
}
};
When onClick called, item.getModelObject() pulls from the sampleEntityListModel which in turn calls mSampleEntityBA.findAll(). The model object of sampleEntityListModel will be cached for the duration on the request cycle (until it is detached - which is usually what you want) and is not aware of the call to delete().
In order to refresh the sampleEntityListModel, add a sampleEntityListModel.detach() call just after the delete (sampleEntityListModel must be made final, but this will not cause any extra state to be serialized). This will cause the model to fetch a fresh set of data when the list view is rendered later in the request cycle.
You probably want an AjaxLink instead of that Link, and then you have to make the list refresh, using the tactics described here, possibly adjusting a bit for the fact that the wiki has Wicket 1.3 code instead of 1.4.
But you might also be better off with a different repeater, such as a RefreshingView or a DataView. There are some examples of assorted repeaters here. While none of them are exactly what you're looking for, looking at that code might help.
looks like the problem is that your mSampleEntityBA.findAll(); is returning incorrect data. hard to help without seeing more code.
on a different note, you should really be using DataView when working with database-backed lists.
You might also want to check out JQGrid from the wiQuery project instead of DataView.