A couple of months ago I bought myself an HTC ONE X. I admired they way they guide the user in taking his first steps in the phone with interactive widgets and help functions.
I would like to add this kind of functionality to Rogerthat, the app we are building, but I wonder if there are tools / libraries that can help me achieve this?
Roman Nurik put together a library called "Wizard Pager" to do this sort of thing. It could likely be used to do what you're asking.
https://plus.google.com/113735310430199015092/posts/6cVymZvn3f4
http://code.google.com/p/romannurik-code/source/browse/misc/wizardpager
Update:
I think this might also be helpful to you. It's similar to the tour shown when first running a stock Android rom in ICS+.
The library can be used in any version of Android:
https://github.com/Espiandev/ShowcaseView
If you want consecutive showcases you can look at this expansio:
https://github.com/blundell/ShowcaseViewExample
I did a guided tour for my app that allows the user to navigate through 4 note pages ans see the instructions. Here's the code:
public static void tour(final Context context, final String title, final int pageNumber,
final Drawable icon, final String[] pageMessage, final int[] layouts, final ViewGroup root) {
Builder tourDialog = new AlertDialog.Builder(context);
int nPage = 0;
if (pageMessage!=null){
tourDialog.setMessage(pageMessage[pageNumber]);
nPage = pageMessage.length;
}
if (layouts!=null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View layout1 = inflater.inflate(layouts[pageNumber], root);
tourDialog.setView(layout1);
//tourDialog.setView(views[pageNumber]);
nPage = layouts.length;
}
tourDialog.setTitle(title+" (page "+(pageNumber+1)+"/"+nPage+")");
tourDialog.setPositiveButton("Prev",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
tour(context, title, pageNumber-1, icon, pageMessage,layouts, root);
return;
}
});
tourDialog.setNeutralButton("Next",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
tour(context, title, pageNumber+1, icon, pageMessage,layouts, root);
return;
}
});
tourDialog.setNegativeButton("Ok",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
return;
}
});
if (icon!=null)
tourDialog.setIcon(icon);
AlertDialog dialog = tourDialog.create();
dialog.show();
if (pageNumber==0)
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
else if (pageNumber==nPage-1){
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setEnabled(false);
}
}
Example of usage:
int[] layout = {R.layout.note1, R.layout.note2, R.layout.note3, R.layout.note4}; //resource id of each page's layout
tour(context, "Notes ", 0,getResources().getDrawable(R.drawable.gmpte_logo_25px),null, layout, (ViewGroup) findViewById(R.id.root));
and an example of note page layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/root"
android:padding="10dip">
<TextView android:id="#+id/text_before"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:textSize="16dp"
android:text="#string/note1_before_text"
android:layout_marginTop="10dp"/>
<ImageView android:id="#+id/image"
android:contentDescription="#string/desc"
android:src="#drawable/mylocation_blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/text_before"
/>
<TextView
android:id="#+id/text_after"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/text_before"
android:layout_below="#+id/image"
android:text="#string/note1_after_text"
android:textColor="#FFF"
android:textSize="16dp" />
</RelativeLayout>
You need to write your own layout for each note page, but use the same id (android:id="#+id/root") for the root layout in each page.
The Showcase View Library is definitely what you want:
Use a ViewPager and a fragment to show your help screens. You'll find plenty information about that.
I wrote little library
That contains a simple component for making a app tour.
It`s very restricted to my case but maybe could be your case .
Single LessonCardView Showed onstartactivity for the first time
or on button click
Any criticism ,help or advice will be appreciated. thanks
https://github.com/dnocode/DnoLib
You can try TourGuide http://worker8.github.io/TourGuide
It's fairly up-to-date (uses Kotlin 1.2) and works pretty nicely.
Most of the alternatives I've checked recently (in 2021), are either not working or buggy.
TourGuide is not perfect (it's been 3 years since it's last commit), and the maintainer doesn't seem to respond to PRs or issues.
Related
I have been using Espresso to carry out automated UI testing with an Android app. (I have been trying to find a resolution to the issue whilst at home from work, so I don’t have the exact examples and errors, but I can update tomorrow morning). I have run into an issue with unit testing buttons within a layout that is included multiple times within a single user interface. Below is a quick example:
<include
android:id="#+id/include_one"
android:layout="#layout/boxes" />
<include
android:id="#+id/include_two"
android:layout="#layout/boxes" />
<include
android:id="#+id/include_three"
android:layout="#layout/boxes" />
Here is an example of what is within the #layout/boxes:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button1" />
<Button
android:id="#+id/button2" />
</RelativeLayout>
I am seemingly unable to access button one within the include I want “include_one”, without accessing all three of the buttons.
I have tried accessing the buttons with the following:
onView(allOf(withId(R.id.include_one), isDescendantOfA(withId(R.id.button1)))).perform(click());
and
onView(allOf(withId(R.id.button1), hasParent(withId(R.id.include_one)))).perform(click());
Both of which I found from this answer: onChildView and hasSiblings with Espresso Unfortunately I haven’t had any success!
I know this isn’t great, but as I am not with my work computer I can’t tell you the exact errors I have come across, but I have encountered:
com.google.android.apps.common.testing.ui.espresso.AmbiguousViewMatcherException
also an error telling me there were no matches found.
The code I am using makes sense, although I am new to using Espresso Can anyone offer some advice, or point out what I may be misunderstanding?
This is a common pitfall when trying to <include/> the same custom xml several times in the same layout.
If you now try calling
Button button1 = (Button) findViewById(R.id.button1);
since the boxes.xml is included more than once, you will always get as a result the button present in the first sub layout, and never another one.
You were pretty close but you need to use the withParent() view matcher.
onView(allOf(withId(R.id.button1), withParent(withId(R.id.include_one))))
.check(matches(isDisplayed()))
.perform(click());
I had similar issue, applied accepted answer but didn't work. Hereby I come across look into expected level of parent hierarchy
private static final class WithParentMatcher extends TypeSafeMatcher<View> {
private final Matcher<View> parentMatcher;
private int hierarchyLevel;
private WithParentMatcher(Matcher<View> parentMatcher, int hierarchyLevel) {
this.parentMatcher = parentMatcher;
this.hierarchyLevel = hierarchyLevel;
}
#Override
public void describeTo(Description description) {
description.appendText("has parent matching: ");
parentMatcher.describeTo(description);
}
#Override
public boolean matchesSafely(View view) {
ViewParent viewParent = view.getParent();
for (int index = 1; index < hierarchyLevel; index++) {
viewParent = viewParent.getParent();
}
return parentMatcher.matches(viewParent);
}
}
Then create a helper method
public static Matcher<View> withParent(final Matcher<View> parentMatcher, int hierarchyLevel) {
return new WithParentMatcher(parentMatcher, hierarchyLevel);
}
Here is the usage
onView(allOf(withId(R.id.button1), withParent(withId(R.id.include_one), 2))).perform(click());
I rarely worked on image views in android. I want to display image view after some interval every time as I want to display ads on it from server. I want to pass Image view in a function as image view. But I don't know how to pass image view from oncreate as I worked on adapter class and where integer array of drawable images does the work properly.
please suggest me how to pass image view as I tried to pass and tried lot of conversions but failed.
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// here i want to take image and pass it on via loadphoto
loadPhoto(R.drawable.ic_launcher, 400, 100);
}
private void loadPhoto(ImageView imageView, int width, int height) {
ImageView tempImageView = imageView;
AlertDialog.Builder imageDialog = new AlertDialog.Builder(this);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.activity_main,
(ViewGroup) findViewById(R.id.layout_root));
ImageView image = (ImageView) layout.findViewById(R.id.fullimage);
image.setImageDrawable(tempImageView.getDrawable());
imageDialog.setView(layout);
imageDialog.setPositiveButton("OK", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
imageDialog.create();
imageDialog.show();
}
}
actvity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:padding="10dp" >
<ImageView
android:id="#+id/fullimage"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ImageView>
<TextView
android:id="#+id/custom_fullimage_placename"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF" >
</TextView>
</LinearLayout>
Thanks in advance
Display image view after some interval every time as I want to display ads on it from server
It means you should use (need) a Timer task (for simple) or a schedule thread to make it runnable.
in new Runnable() {
// Your work here:
// Load the image
}
Also notice : update the image is excuted on UI thread.
Oh sorry, may be too far with your question.
If you already had your images (in your drawable/ in raw/ folder), i suggest you parse an interger, for example loadPhoto(Integer imageSourceID, Context mContext) and load it, using getResource()
If you get it from server (download), then asynctask would be a good choice. Prepare your UI in onPreExcute, do your work in onDoinBackground() and update in the onPostExcute()
I hope these will help you
4.
To all,
I am trying to get a simple NumberPicker to work in a AlertDialog. The problem is that whenever I increase/decrease the value in the numberpicker, the keyboard activates.
There are many posts describing this problem, but none of the suggestions work.
I have tried:
android:configChanges="keyboard|keyboardHidden"
And
inputManager.hideSoftInputFromWindow(currentView.getWindowToken(), 0);
And
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
I have tried calling these functions before and after initialization (dialog.show ()), on keypress events (using listeners obviously), etc. but no luck so far.
The complete code:
popup.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<NumberPicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/myNumber"
android:configChanges="keyboard|keyboardHidden"
/>
</RelativeLayout>
And the calling function:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
} });
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
} });
View view = getLayoutInflater().inflate(R.layout.popup, null);
builder.setView (view);
final AlertDialog dialog = builder.create ();
NumberPicker picker = (NumberPicker) view.findViewById(R.id.myNumber);
picker.setMinValue(0);
picker.setMaxValue(999);
dialog.getWindow().
setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
dialog.show();
Any help appreciated
Barry
Actually, although the solution above works perfectly, there is an easier way.
picker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
This is all that is needed. Anyway, thanks for the replies!!!! :-)
Since there is no access to NumberPicker buttons, it's "impossible" to do.
I made fast dirty hack to deal with it.
First add focus eater to layout, in this case Button with 0 size:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<NumberPicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/myNumber"
android:configChanges="keyboard|keyboardHidden"
/>
<Button
android:id="#+id/myBtn"
android:layout_width="0dp"
android:layout_height="0dp"
/>
</RelativeLayout>
We need to catch event of clicking on incement/decrement buttons, I chose OnValueChangedListener, couldn't find something better.
EditText edit = null;
try {
final Field[] fields = picker.getClass().getDeclaredFields();
for (Field f : fields) {
if (EditText.class.equals(f.getType())) {
f.setAccessible(true);
edit = (EditText) f.get(picker);
}
}
} catch (IllegalAccessException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
if (edit != null) {
final EditText finalEdit = edit;
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
picker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker numberPicker, int i, int i1) {
dialog.findViewById(R.id.myBtn).requestFocusFromTouch();
imm.hideSoftInputFromWindow(finalEdit.getWindowToken(), 0);
}
});
}
This is not recommended solution. I hope someone would find something better.
Use only for educational purpose ;-)
the android:configChanges attribute belongs in your Manifest.xml file, not the layout. But if you are hiding the keyboard from there, you are probably best of using
android:windowSoftInputMode="stateAlwaysHidden"
You should also try to use getWindow() on your Activity rather than just the Dialog and see if that helps. This is probably the best solution as the first one (hiding from the manifest) will keep the keyboard hidden throughout the entire Activity.
XML:
<NumberPicker
...
android:descendantFocusability="blocksDescendants" />
What I am trying to do is to create a custom dialog that overrides an AlertDialog.
What it is supposed to do is get some text (at least 2 strings) and then for each of those strings it is supposed to be able to get more information, but I want to do this in custom dialogs.
So what is supposed to happen is a user can enter 2 people in an activity screen, and then for the first person, you get a custom dialog and that person can enter three words, and then it jumps to the next custom dialog (exact same layout I am inflating) and the second person can enter some words.
This is my xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinLay_Enter_Words"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/TextView_AddPlayerWord_Instruction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/help_text_size"
android:textStyle="bold"></TextView>
<EditText
android:id="#+id/EditText_Word1"
android:layout_height="wrap_content"
android:maxLength="20"
android:layout_width="match_parent"
android:maxLines="1"></EditText>
<EditText
android:id="#+id/EditText_Word2"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:maxLines="1"></EditText>
<EditText
android:id="#+id/EditText_Word3"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:maxLines="1"></EditText>
</LinearLayout>
And this is part of the code:
protected Dialog onCreateDialog(int id) {
switch (id) {
case NOUN_INPUT_DIALOG_ID:
Dialog returnedDialog = initWordDialog();
return(returnedDialog);
}
return null;
}
It calls initWordDialog():
private Dialog initWordDialog() {
LayoutInflater inflater = LayoutInflater.from(this); //(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View dialogLayout = inflater.inflate(R.layout.word_entry_dialog, null);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
...
TextView v1 = (TextView) dialogLayout.findViewById(R.id.TextView_AddPlayerWord_Instruction);
...
v1.setText("SomeText");
builder.setView(dialogLayout);
builder.setTitle(R.string.enter_word_title);
builder.setPositiveButton("Next", onNextSubmit);
AlertDialog wordBuilderDialog = builder.create();
return wordBuilderDialog;
}
I think what I am trying to find has been discussed to some degree here:
Value of EditText in Custom Dialog
Android - Custom Dialog - Can't get text from EditText
How to add two edit text fields in an alert dialog
The problem, I believe, lies here, where all of the examples everyone has their onClick in the same function as their onCreate. My stuff was a bit more complicated and I wanted to separate out the functions; however, as a result, I am now unable to access any of the EditText variables.
Here is my onClick implementation:
private DialogInterface.OnClickListener onNextSubmit = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (setPlayerWords()) {
...
}
};
The part that matters is I don't even get to the part where I'm accessing the edittexts until setPlayerWords is called, and this is where it is failing:
public boolean setPlayerWords() {
PMGamePlay pmObj = (PMGamePlay) getApplicationContext();
String[] playerWords = new String[pmObj.numberOfWordsPlayersGetToInput()];
//LayoutInflater inflater = LayoutInflater.from(this);
//View dialogLayout2 = inflater.inflate(R.layout.word_entry_dialog, null);
//setContentView(R.layout.word_entry_dialog);
final LinearLayout myLayout = (LinearLayout) findViewById(R.id.LinLay_Enter_Words);
final EditText w0 = (EditText) myLayout.findViewById(R.id.EditText_Word1);
final EditText w1 = (EditText) myLayout.findViewById(R.id.EditText_Word2);
final EditText w2 = (EditText) myLayout.findViewById(R.id.EditText_Word3);
String test = w0.getText().toString();
playerWords[0] = w0.getText().toString();
playerWords[1] = w1.getText().toString();
playerWords[2] = w2.getText().toString();
...
return true;
}
I initially tried re-inflating, but that seemed to reset and while the edittexts would not be null, they were reset to have "" in their values.
Then I tried to setContentView on my xml file, but that still gave me a null value.
Now, I just try and simply access the linearlayout, and that also returns a null value. If I just try to access the edittexts by their id directly without first going through its parent linearlayout, it also returns a null value.
At this point, I'm not sure what to do other than to cram everything that I have in these separate functions into the same single onclick, but I really don't want to do that. Is there nothing else I can do to access these edittexts?
Any help would be greatly appreciated!
Have you tried using the long version of inflate inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) ? I know that if you don't use this method there can be some issues with it grabbing layout characteristics, so might be causing the issue. For the viewgroup you should pick the parrent view for the alert and usually want attachToRoof = false;
Please see my code below. I am unable to make SetGravity work.
How come?
Layout Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="25dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:longClickable="true"
android:orientation="vertical" >
<EditText
android:id="#+id/etCommands"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Type a command"
android:password="true" />
<LinearLayout
android:weightSum="100"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_weight="20"
android:id="#+id/btnResults"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Results" />
<ToggleButton
android:paddingBottom="10dp"
android:layout_weight="80"
android:id="#+id/passTog"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ToggleButton" android:checked="true"/>
</LinearLayout>
<TextView
android:id="#+id/tvResults"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="invalid" />
</LinearLayout>
java code:
public class TextPlay extends Activity {
private static final String TAG = "MyApp";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.text);
Button chkCmd = (Button) findViewById(R.id.btnResults);
final ToggleButton passTog = (ToggleButton) findViewById(R.id.passTog);
final EditText input = (EditText) findViewById(R.id.etCommands);
final TextView display = (TextView) findViewById(R.id.tvResults);
passTog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (passTog.isChecked()) {
input.setInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_PASSWORD);
} else {
input.setInputType(InputType.TYPE_CLASS_TEXT);
}
}
});
chkCmd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String check = input.getText().toString();
Log.i(TAG, "Check Value is: " + check);
if (check.contentEquals("left")) {
Log.i(TAG, "I am under left ");
display.setGravity(Gravity.LEFT); //WHYW ILL YOU NOT WORK SETGRAVITY?????????????
} else if (check.contentEquals("center")) {
display.setGravity(Gravity.CENTER);
} else if (check.contentEquals("right")) {
display.setGravity(Gravity.RIGHT);
}
else if (check.contentEquals("blue")) {
display.setGravity(Gravity.RIGHT);
}
}
});
}
}
I just tested and it works.. You might be doing a few things wrong;
First of all, when you type "left" into the text field, are you making sure that you didn't type "Left" (most keyboards capitalize the first letter)
If you are sure about the above, do you see the log that says "I am under left " (Not the "Check is")? If not, then it's not getting there somehow..
If you are indeed seeing it, you might want to clean/build your project (in Eclipse Project-> Clean -it does cleaning and re-building)
If that doesn't work neither, you might want to change your target build (change it to API level 10 or so) You don't really need to worry about the target build if you are just using this as an exercise to learn.
I think we're not able to change UI this way.
I usually do like this.
TableLayout table1 = (TableLayout) findViewById(R.id.table1);
txtresult.setGravity(Gravity.RIGHT);
((TableLayout) table1).addView(txtresult);
It works with me.
So I suggest you to do a trick like delete that TextView "display" and generate a new one with new Gravity properties.
Hope it works!
Linh
Try to set layout_gravity="center" and layout_width="wrap_ontent" maybe that will do it :)
set layout_width="wrap_content" and set the layout gravity.
Have you tried to call invalidate after you change the layout attribute of your text view?
Android Documentation - View.invalidate()
Change the conditions as below:
check.equalsIgnoreCase("left")
Hope this solves ur problem.
View.invalidate() must be involved on UI thread. If you are doing the view re-configuration within a Listener callback which is your case, then you probably need call View.postInvalidate(), check out the API:
public void invalidate ()
Since: API Level 1
Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate().
Try this:
<LinearLayout
android:id="#+id/llResults"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center">
<TextView
android:id="#+id/tvResults"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="invalid" />
</LinearLayout>
Instead of Doing :- tvResults.setGravity
try setting gravity of linearlayout :- llResults.setGravity
your code works good for me, i´ve tested on a real device with android 4.0.3 (Nexus S), the only thing that can be bothering you its capital letters as #Tolga E told.
you can try:
check.equalsIgnoreCase("left")
instead of:
check.contentEquals("left")
and debugging, put a breakpoint on the if´s to check that your code is actually trying to modify the gravity or its skipping that line.
Hope it helps.
If anyone who's following thenewboston's tutorial stumbles upon this with the same problem, it's an issue with the display variable. Just change
final TextView display = (TextView) findViewById(R.id.tvDisplay);
to
final TextView display = (TextView) findViewById(R.id.tvResults);
up with the other variable declarations.
I think setGravity method has been depreciated from API 4.0 . I don't see any alternative. Only way left you need to use API level 8.0. I am also getting nulpointer exceptions in log cat by using setGravity method
Set your TextView's width as android:layout_width="fill_parent"then you can set it programmatically using myTextView.setGravity(Gravity.CENTER) .