I have a program that handles song objects with some fields and playlist objects that are arrays of the songs. I have a perfectly functioning java programming that does what I need it to do but I'm trying to convert it into an Android app and it's making me want to throw my computer out the window. I don't really know XML but I've gotten the basics such as creating buttons etc.
I have a button in the layout file that I implemented as follows:
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="#string/Button"
android:onClick="newPlaylist"/>
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/button1"
android:layout_below="#+id/button1" />
In my main file I have:
public void newPlaylist(View view){
Playlist list1 = new Playlist("First Playlist");
TextView first = (TextView) findViewById(R.id.textView1);
first.setText(list1.getName());
}
Edit: I was able to add a little to the newPlaylist method. Now when I click the button it displays the name of the playlist, but I still want to edit it and be able to have multiple playlists on the screen to manipulate.
All I want to do is display the playlist name as either a text or label that is clickable so that the name can be changed and I can move on from here.
The Android documentation on the button component might help you with your problem.
I assume that your Playlist class looks something like this
public class Playlist {
private String name;
public Playlist(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
If it does, then your method for handling the button click should look like this.
public void newPlaylist(View view) {
Playlist playlist = new Playlist("My First Playlist!"); // Create our playlist object
// Since button is the only component that uses 'newPlaylist' as a click listener, the view will always be the button
Button button = (Button) view; // We cast the view to button
button.setText(playlist.getName()); // This edits the button text, might want to create a TextView for this
}
Related
I'm trying to re-rig a quiz app to instead of displaying text questions, will display images (Ishihara slides to be specific).
For reference, here's a screenshot of the original quiz app:
When a user selects the true or false buttons, a toast appears with the result. Straightforward, and the previous/next buttons cycle through the questions. The questions are being stored as such:
final QuestionAndAnswer[] mQandA = new QuestionAndAnswer[]{
/*1*/ new QuestionAndAnswer(R.string.question_northAmerica, true),
/*2*/ new QuestionAndAnswer(R.string.question_antarctica, false),
/*3*/ new QuestionAndAnswer(R.string.question_canada, false),
/*4*/ new QuestionAndAnswer(R.string.question_madagascar, true),
/*5*/ new QuestionAndAnswer(R.string.question_wonders, false)
};
I thought that pointing the new QuestionAndAnswer at R.drawable.imagename could accomplish this, but instead just displays the image's location as text.
And changing it to new ImageView(R.drawable.imagename, true) throws the error:
ImageView (android.content.Context, android.util.AttributeSet)in ImageView cannot be applied to (int,boolean)
I'm sorry, I'm still very new to Android but as you've probably put together by now, I'm a student and don't have a choice but to do this.
If you have something like this on layout xml
<RelativeLayout ...
...
<TextView android:id="#+id/text_view_id" ... />
...
</RelativeLayout>
You need to change it to
<RelativeLayout ...
...
<ImageView android:id="#+id/image_view_id" ... />
...
</RelativeLayout>
Then on your activity class, maybe you have something like below
TextView textView;
public void onCreate() {
textView = (TextView) findViewById(R.id.text_view_id);
....
textView.setText(mQandA[i].question)
}
Where mQandA[i].question is your question resource a.k.a R.string.question_northAmerica
Change it to
ImageView imageView;
public void onCreate() {
imageView = (ImageView) findViewById(R.id.image_view_id);
...
imageView.setImageResource(mQandA[i].question)
}
Where mQandA[i].question is your image resource a.k.a R.drawable.imagename
EDIT 1
change every appearance of
textView.setText(mQandA[i].question)
with
imageView.setImageResource(mQandA[i].question)
counterpart
I am creating an app in Android where I have a button that displays silly phrases when pressed. I figured out how to get it to say two phrases but I can't figure out how to make it do more. I also want to add in a feature to have the button pick phrases at random instead of going in the order I set. I am thinking of using an arraylist for this. How do I set the button to cycle through different methods in Andrido Studio?
I also want you to know that I am a beginner so please don't be too hard on me.
This is my XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/funny_imageview"
android:scaleType="fitCenter" />
<TextView
android:id="#+id/funny_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text=""/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/funny_sayings_button"
android:text="Click Me!"
android:layout_marginTop="8dp"
android:onClick="changeFunnySayingsButton"/>
</LinearLayout>
This is my Java:
package com.example.android.funnysayingsbutton;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
boolean clicked = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* This method changes the funny text and image on the screen when the button is clicked.
*/
public void changeFunnySayingsButton (View view){
if (clicked){
funnySayingOne();
clicked = false;
}
else {
funnySayingTwo();
clicked = true;
}
}
/**
* This method is for the first funny expression.
*/
public void funnySayingOne(){
displayAnswer("Time to Monkey Around");
displayImage(R.drawable.monkey);
}
/**
* This method is for the second funny expression.
*/
public void funnySayingTwo(){
displayAnswer("Penguin Party Time");
displayImage(R.drawable.penguin);
}
/**
* This method is for the third funny expression.
*/
public void funnySayingThree(){
displayAnswer("It's Rabbit Season.");
displayImage(R.drawable.rabbit);
}
/**
* This method displays the funny text on the screen.
*/
private void displayAnswer(String answer) {
TextView questionTextView = (TextView) findViewById(R.id.funny_textview);
questionTextView.setText(answer);
}
/**
* This method displays the funny image on the screen.
*/
private void displayImage(int picture) {
ImageView questionTextView = (ImageView) findViewById(R.id.funny_imageview);
questionTextView.setImageResource(picture);
}
}
I think that you're on the right track thinking about using a data structure like an ArrayList.
I'd start by making a class to represent each funny thing, e.g.
public class FunnyThing {
private String phrase; // I'd use a resource ID here
private int drawableResourceId;
}
Then it's a matter of initializing the set of FunnyThing objects and storing them in your data structure. You could do this in the onCreate method of your activity, but you may want to consider writing a factory method somewhere else (e.g. the FunnyThing class) that your activity just calls to keep the code from getting cluttered when there are more than 2-3 funny things.
Finally, on each button press you can choose a random index in your collection of FunnyThings and display that, e.g.
private void displayRandomFunnyThing() {
// assumes you have a java.util.Random instance vairable named mRandom
FunnyThing ft = mFunnyThings.get( mRandom.nextInt( mFunnyThings.size());
displayAnswer( ft.phrase );
displayImage( ft.drawableResourceId);
}
Of course you'll need to add an onClickListener to your button, but I'm assuming that you left that code out for brevity.
You'll also have the problem that the phrase selection is random, so you may get the same phrase many times before you see all of them. If you want to prevent duplicates, well, that will take more code.
First of all, where is your button onClick listener? This is where you should add your methods.
Button button = (Button)this.findViewById(R.id.funny_sayings_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
changeFunnySayingsButton (v);
}
});
To continue with you could create an ArrayList of Strings. You add all of your strings and then simply pick one at random from the list. Hint:
//will choose a random number between 0 and the length of the list - 1
int i = rand.nextInt(yourList.size());
String yourFunnyString=yourList.get(i);
If you also want to display an image alongside with the String you should also create a map. Use the String as a key. When you select from yourList then use this key to select the value (your image) from the map.
It should be fairly straightforward to do.
I have the following layout defined in useful_numbers_item_fragment.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/call_linear_layout">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/useful_nums_item_name"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/useful_nums_item_value"/>
</LinearLayout>
<ImageButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/call"
android:id="#+id/call_btn"
android:onClick="callNumber"/>
</LinearLayout>
I dynamically populate the two text views in a class called UNItemListFragment.java
in the onCreate method:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
if (getArguments().containsKey(Constants.UNItem.GROUP_ID)) {
simpleCursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.useful_numbers_item_fragment, null,
new String[]{Constants.UNItem.NAME, Constants.UNItem.VALUE},
new int[]{R.id.useful_nums_item_name, R.id.useful_nums_item_value}, 0);
setListAdapter(simpleCursorAdapter);
getLoaderManager().initLoader(0, getArguments(), this);
}
}
For each number if i click on the button i want to make a phone call by
calling the callNumber method when the user clicks the button:
public void callNumber(View view) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
TextView unItemVal = (TextView) findViewById(R.id.useful_nums_item_value);
String phoneNumber = unItemVal.getText().toString();
callIntent.setData(Uri.parse("tel:" + phoneNumber));
startActivity(callIntent);
}
It is ok when I click the first button in the list, but when I click on the other buttons
it continues calling the number defined in the first row...
Any idea how to resolve this?
The problem is that this line:
TextView unItemVal = (TextView) findViewById(R.id.useful_nums_item_value);
is executed on the activity, so the findViewById will always return the first item with that id, which is likely the first item in the list.
The best way to fix this would be to override the adapter and add a tag containing the phone number to the view. A quick way to fix this would be to tag along in the view hierarchy, like so:
public void callNumber(View view) {
if( view != null ) { // view is the button tapped
View parent = view.getParent(); // this should be the LinearLayout
if( parent instanceof LinearLayout ) {
TextView unItemVal = (TextView) ((LinearLayout)parent).findViewById(R.id.useful_nums_item_value);
if( unItemVal != null ) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
String phoneNumber = unItemVal.getText().toString();
callIntent.setData(Uri.parse("tel:" + phoneNumber));
startActivity(callIntent);
}
}
}
}
This would find the parent for the button that was clicked, and then find the text-view containing the number within that ViewGroup.
Using findViewById() will return the first view in the activity or fragment with the specified id. If this is a ListView, it will correspond to the first row.
There are many ways to work around this problem. The quickest one (but certainly not the prettiest one, since it depends on the layout) would be to use findViewById() relative to the LinearLayout that contains the list item. Assuming that view is the ImageButton, it would be somthing like:
((View)view.getParent()).findViewById(R.id.useful_nums_item_value)
A more elegant solution would be to set a tag in the adapter's getView(), containing the data you need (in this case, the phone number to call).
I am creating a times tables app, in which one of the activities allows the user to enter which times tables they would like to view, then the app will bring up that times tables.(e.g. 6x5=30) etc.
Below is the xml layout I have created for the activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="15dp">
<TextView
android:id="#+id/tvTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I want to see the: "
android:textSize="25dp" />
<EditText
android:id="#+id/etEnterNumber"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter Number..."
>
</EditText>
<TextView
android:id="#+id/tvBottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Times tables!"
android:textSize="25dp" />
<Button
android:id="#+id/btnGo"
android:layout_width="50dp"
android:layout_height="50dp"
android:text="Go"
android:layout_gravity="center"/>r
</LinearLayout>
And this it the java class I have created thus far for the classes functionalitiy:
public class ViewTimesTables extends Activity implements View.OnClickListener {
// Declaring Vars
Button go;
EditText enterNumber;
TextView top;
TextView bottom;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setting equal to text layout View
setContentView(R.layout.view);
// calling method to intialise vars
initialiseVars();
}// on create end
/**
* method to initialise all of the buttons, textviews etc used to clean up
* the onCreate.
*/
private void initialiseVars() {
// Setting up (initialising) all the buttons text views etc from the xml
// (vid 25)
go = (Button) findViewById(R.id.btnGo);
enterNumber = (EditText) findViewById(R.id.etEnterNumber);
top = (TextView) findViewById(R.id.tvTop);
bottom = (TextView) findViewById(R.id.tvBottom);
}
/**
* Method with on click listener that adds functionality for all of the
* buttons, text views etc
*
* #param v
*/
public void onClick(View view) {
// switch statement which determines what is clicked
switch ((view).getId()) {
case R.id.etEnterNumber:
// code to read user number (i.e. between 1 and 12)
//And possibly link to go button
break;
case R.id.btnGo:
// code to bring up new activity/screen with times table
// of the number that was entered in edit text
break;
}
}
}
I am unsure how to add the correct functionality (probably within switch statement) so that when e.g. "6" is entered in the edit text box and the "go" button is pressed then the 6 times tables will be brought up in a new activity?
I would begin by looking at Intents to start a new activity and pass data to it.
A relevant tutorial is this Android Intents Tutorial
Getting the text from a edit text is a simple as enterNumber.getText().getString()
You could then use a conditional statement to call the designated class.
Something like this would allow you to pass two values to the SixTimesTables class with the values 5 and 6 passed in.
if(enterNumber.getText().getString().equals("6")){
Intent i = new Intent(this, SixTimesTables.class);
i.putExtra("Value1", 5);
i.putExtra("Value2", 6);
// set the request code to any code you like,
// you can identify the callback via this code
startActivityForResult(i, REQUEST_CODE);
}
You probably want a dynamic layout for next activity.
It may help you.
http://www.dreamincode.net/forums/topic/130521-android-part-iii-dynamic-layouts/
Then you can switch between activities as AndyGable mentioned.
Hopefully it'll help you.
You really dont need the onClick for the editText you can handle if data is entered in the editText or not from the button click only like this:
public void onClick(View view) {
// switch statement which determines what is clicked
switch ((view).getId()) {
case R.id.btnGo:
// code to bring up new activity/screen with times table
// of the number that was entered in edit text
// check if editText has values or not
if(TextUtils.isEmpty(mEditText.getText().toString())) {
mEditText.setError("Please enter a number");
}else {
int number = Integer.parseInt(mEditText.getText().toString());
Intent intent = new Intent(YourCurrentActivity.this, NextActivity.class);
intent.putExtra("value", number);
startActivity(intent);
// it is always good to check if the value entered is a number only or not
// add inputType tag in the xml
// android:inputType="number" for the editText.
}
break;
}
}
Now, in order to get value in the next activity do this:
// write this inside the onCreate of the Activity.
int number;
if(getIntent().getExtras() != null) {
number = getIntent().getIntExtra("value");
}
// use the number then to display the tables
I am relatively new to Android development but I do have a pretty good understanding of Java and xml etc. so excuse me if this is an easy question and I just can't put two and two together.
Anyway, I am trying to have a user input a few characters into an EditText field. When they press a Button, it will call a method that will output a String. I then want this String to be displayed on the same activity as the EditText field and Button.
How do I go about taking the String variable that is the result of the method and putting into a String in the strings.xml file?
See this question. I don't think that is possible, what you probably want to do is store what the user enters in SharedPreferences.
EDIT:
To take the string variable and display it on the screen you would want to add a TextView to your layout:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text=""/>
Then in code you will add a listener to your button to listen for click events, and have a reference to the TextView in your class:
Fields in class:
TextView tv;
Button myButton;
EditText et;
onCreate():
tv = (TextView)findViewById(R.id.textview);
myButton = (Button)findViewById(R.id.button);
et = (EditText)findViewById(R.id.edittext);
//Now set the onclick listener:
myButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(args....)
{
String txt = et.getText().toString();
tv.setText(txt);
}
});
Also check out this tutorial.