Add a text field on button click to second main activity - java

I need to add text field depends on the number the user added in the number text field to the second main activity. I already have a button that open onClick a new MainActivity but I need also to add text fields in the second MainActivity depends the number added.
I tried adding text fields on actionListeners but still not working.
public class MainActivity extends AppCompatActivity {
private Button submit_textfield;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
submit_textfield = (Button) findViewById(R.id.submit_textfield);
submit_textfield.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
openActivity2();
}
});}
public void openActivity2() {
Intent intent = new Intent(this, Main2Activity.class);
startActivity(intent);
}
}
The results must be: the user enters 5 and click submit the page redirect and creates 5 text fields. Thank You.

the user enters 5 and click submit the page redirect and creates 5
textfields
For this, you need to pass the text value into another class by using Intent.
Then you can receive the value by using getIntExtra in Main2Activity.
public void openActivity2() {
Intent intent = new Intent(this, Main2Activity.class);
intent.putExtra("num",submit_textfield.getText());
startActivity(intent);
}
After get the num value, you can create the TextView dynamically based on the number.
Main2Activity
int num = getIntent().getIntExtra("num",0);
LinearLayout linearLayout = findViewById(R.id.myLinearLayout);
for (int i = 0; i < num; i++) {
final TextView rowTextView = new TextView(this);
rowTextView.setText("Value " + i);
myLinearLayout.addView(rowTextView);
}
Output

For achieving this you have to add a dynamic linear layout in which you will add textviews on run time nad firstly you have to pass that number into the intent by putExtra method.
public void openActivity2() {
Intent intent = new Intent(this, Main2Activity.class);
intent.putExtra("number",submit_textfield.getText().toString());
startActivity(intent);
}
Now you just have to get this value in the next activity and start a for loop for this value and add runtime textviews in the linear layout.
int number =0;
if(getIntent().getExtras()!=null){
number = Integer.parseInt(getIntent().getStringExtra("number"));
}
LinearLayout ll= findViewById(R.id.ll_layout);
for (int i = 0; i < num; i++) {
final TextView tv_text= new TextView(this);
tv_text.setText("Value " + i);
ll.addView(tv_text);
}
if you want to set these textviews in vertical orientation then you just have to add the params to the linear layout as mentioned below:
ll.setOrientation(LinearLayout.VERTICAL);

Related

Save data in ArrayList in activity

I am a new android programmer.
I have 4 activities: A B C D.
The order is A -> B -> C -> D -> A and A -> D using buttons.
I want to save data in ArrayList that is in activity D.
The problem is that when I move from D to A and come back to D, the data in the ArrayList didn't save.
Code for D activity here:
public class SchedulerActivity extends AppCompatActivity {
public String name = "";
public String number = "";
public String date = "";
public String hour = "";
public ArrayList<EventClass> scheduler = new ArrayList<>();
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scheduler);
Bundle extras = getIntent().getExtras();
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(SchedulerActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
finish();
}
});
if (extras != null) {
String sender = extras.getString("sender");
if(sender.compareTo("Hours") == 0) {
name = extras.getString("name");
number = extras.getString("number");
date = extras.getString("date");
hour = extras.getString("hour");
Date real_date = new Date();
SimpleDateFormat formatter1=new SimpleDateFormat("dd/MM/yyyy");
try {
real_date = formatter1.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
scheduler.add(new EventClass(real_date, name, number, "", hour));
for (EventClass event : scheduler){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
final TextView t = new TextView(this);
t.setText(event.toString());
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
linearLayout.addView(t, params);
}
}
else{
for (EventClass event : scheduler){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
final Button btn = new Button(this);
final TextView t = new TextView(this);
t.setText(event.toString());
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
linearLayout.addView(btn, params);
}
}
}
}
I want to change my ArrayList when C->D occurs and print it and when D->A occurs I just want to print it. I know that I can with SharedPreferences but for the first step, I want to do this with ArrayList.
What's the best way to do this?
Creating static objects is not a good approach. So you can use android activity stack in-place of using static Arraylist. Android activities are stored in the activity stack. Going back to a previous activity could mean two things.
You opened the new activity from another activity with startActivityForResult. In that case you can just call the finishActivity() function from your code and it'll take you back to the previous activity.
Keep track of the activity stack. Whenever you start a new activity with an intent you can specify an intent flag like FLAG_ACTIVITY_REORDER_TO_FRONT or FLAG_ACTIVITY_PREVIOUS_IS_TOP. You can use this to shuffle between the activities in your application.
The scheduler is a non-static field in the SchedulerActivity which means that its existance is tied to the instance of the activity. When the activity instance is destroyed, and that might happen for example when the screen orientation is destroyed or you move to another activity, so are all its non-static fields. You can change that by adding a static keyword before your field:
public static ArrayList<EventClass> scheduler = new ArrayList<>();
Now, your field is tied to the class itself, not the instance, whitch means it wont be destroyed along with the instance. But it also means that it is shared between all instances and must be referenced with the class name outside of the class body:
EventClass event = SchedulerActivity.scheduler.get(0)
A good approach is saving your data in a local database, like Room. You need to save before go to new activity, and get it back on OnResume().

How to dynamically add items to GridView Android Studio (Java)

Hello I want to have an Add function that allows me to input items to my GridView
For Background: I have a standard GridView and an XML activity (which contains 2 TextView) that I want to convert to my GridView. I also have a custom ArrayAdapter class and custom Word object (takes 2 Strings variables) that helps me do this.
My problem: I want to have an Add button that takes me to another XML-Layout/class and IDEALLY it input a single item and so when the user goes back to MainActivity the GridView would be updated along with the previous information that I currently hard-coded atm. This previous sentence doesn't work currently
Custom ArrayAdapter and 'WordFolder' is my custom String object that has 2 getters
//constructor - it takes the context and the list of words
WordAdapter(Context context, ArrayList<WordFolder> word){
super(context, 0, word);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View listItemView = convertView;
if(listItemView == null){
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.folder_view, parent, false);
}
//Getting the current word
WordFolder currentWord = getItem(position);
//making the 2 text view to match our word_folder.xml
TextView title = (TextView) listItemView.findViewById(R.id.title);
title.setText(currentWord.getTitle());
TextView desc = (TextView) listItemView.findViewById(R.id.desc);
desc.setText(currentWord.getTitleDesc());
return listItemView;
}
}
Here is my NewFolder code. Which sets contentview to a different XML. it's pretty empty since I'm lost on what to do
public class NewFolder extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_folder_view);
Button add = (Button) findViewById(R.id.add);
//If the user clicks the add button - it will save the contents to the Word Class
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//make TextView variables and cast the contents to a string and save it to a String variable
TextView name = (TextView) findViewById(R.id.new_folder);
String title = (String) name.getText();
TextView descText = (TextView) findViewById(R.id.desc);
String desc = (String) descText.getText();
//Save it to the Word class
ArrayList<WordFolder> word = new ArrayList<>();
word.add(new WordFolder(title, desc));
//goes back to the MainActivity
Intent intent = new Intent(NewFolder.this, MainActivity.class);
startActivity(intent);
}
});
}
In my WordFolder class I made some TextView variables and save the strings to my ArrayList<> object but so far it's been useless since it doesn't interact with the previous ArrayList<> in ActivityMain which makes sense because its an entirely new object. I thought about making the ArrayList a global variable which atm it doesn't make sense to me and I'm currently lost.
Sample code would be appreciative but looking for a sense of direction on what to do next. I can provide other code if necessary. Thank you
To pass data between Activities to need to do a few things:
First, when the user presses your "Add" button, you want to start the second activity in a way that allows it to return a result. this means, that instead of using startActivity you need to use startActivityForResult.
This method takes an intent and an int.
Use the same intent you used in startActivity.
The int should be a code that helps you identify where a result came from, when a result comes. For this, define some constant in your ActivityMain class:
private static final int ADD_RESULT_CODE = 123;
Now, your button's click listener should looks something like this:
addButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent=new Intent(MainActivity.this, NewFolder.class);
startActivityForResult(intent, ADD_RESULT_CODE);
}
});
Now for returning the result.
First, you shouldn't go back to your main activity by starting another intent.
Instead, you should use finish() (which is a method defined in AppCompatActivity, you can use to finish your activity), this will return the user to the last place he was before this activity - ActivityMain.
And to return some data, too, you can use this code:
Intent intent=new Intent();
intent.putExtra("title",title);
intent.putExtra("desc",desc);
setResult(Activity.RESULT_OK, intent);
where title and desc are the variables you want to pass.
in your case it should look something like this:
public class NewFolder extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_folder_view);
Button add = (Button) findViewById(R.id.add);
//If the user clicks the add button - it will save the contents to the Word Class
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//make TextView variables and cast the contents to a string and save it to a String variable
TextView name = (TextView) findViewById(R.id.new_folder);
String title = (String) name.getText();
TextView descText = (TextView) findViewById(R.id.desc);
String desc = (String) descText.getText();
//Save it to the Word class
ArrayList<WordFolder> word = new ArrayList<>();
word.add(new WordFolder(title, desc));
Intent intent=new Intent();
intent.putExtra("title",title);
intent.putExtra("desc",desc);
setResult(Activity.RESULT_OK, intent);
//goes back to the MainActivity
finish();
}
});
}
You should probably also take care of the case where the user changed his mind and wants to cancel adding an item. in this case you should:
setResult(Activity.RESULT_CANCELLED);
finish();
In your ActivityMain you will have the result code, and if its Activity.RESULT_OK you'll know you should add a new item, but if its Activity.RESULT_CANCELLED you'll know that the user changed their mind
Now all that's left is receiving the data in ActivityMain, and doing whatever you want to do with it (like adding it to the grid view).
To do this you need to override a method called onActivityResult inside ActivityMain:
// Call Back method to get the Message form other Activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
// check the result code to know where the result came from
//and check that the result code is OK
if(resultCode == Activity.RESULT_OK && requestCode == ADD_RESULT_CODE )
{
String title = data.getStringExtra("title");
String desc = data.getStringExtra("desc");
//... now, do whatever you want with these variables in ActivityMain.
}
}

How to add multiple edit text automatically on Android?

I am new to the Android and I am currently working on my android project.
I want to do this...
On the first Activity, the user will enter the number of strings he/she wants to input. For example, 3. (I am already done with this.)
And then, on the second activity, three edit text will appear for the entering the first, second and third string based on the user input in the first activity. If he/she enters 2, two edit text will appear on the second Java Activity. (How to do this one?)
In your Activity1, pass the user's entry to the next activity:
int userSelectedVal=somevalue;
Intent mIntent = new Intent(Activity1.this, Activity2.class);
mIntent.putExtra("userSelectedVal", userSelectedVal);
startActivity(mIntent);
In your Activity2, retrieve this value and programmatically add the Edittext's depending on this value:
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
int noOfEditTexts = extras.getInt("userSelectedVal");
LinearLayout mLinearlayout = new LinearLayout(this);
// specifying vertical orientation
mLinearlayout.setOrientation(LinearLayout.VERTICAL);
// creating LayoutParams
LayoutParams mLayoutParam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
// set LinearLayout as a root element of the screen
setContentView(mLinearlayout, mLayoutParam);
for (int i = 0; i < noOfEditTexts; i++) {
EditText mEditText = new EditText(context); // Pass it an Activity or Context
myEditText.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
mLinearlayout.addView(mEditText);
}
}

Back button restores modified text Views

I will simplify my code to address the problem specifically:
I have an activity A with some TextViews, which text is set to certain key values stored in SharedPreferences, in the activity's OnCreate method. Each textview has a button besides it. When a button is clicked it opens a new activity B which displays an adapter with different text strings. When the user clicks one, the new string is stored in preferences and the user is directed back to Activity A through an intent, and so OnCreate method is called and the textview is updated with the selected text. This works perfectly.
However, my problem is:
When a user does this and updates the textview, if they press Back button once, it will take them to Activity B, but if pressed twice that will take them to Activity A before updating the TextView and thus displaying the old textview, despite having stored in SharedPreferences the updated value. How can this be fixed?
A more simplified version of my problem is, I have a TextView in my layout, and a button which if pressed, deletes it and refreshes the Activity. User presses the delete button, text view disappears, but then presses back button and TextView is restored. That's what I dont want.
I have researched all the back button methodologies and savedInstanceState documentation but I still havent found something that works. I also tried adding an UpNavigation button in my action bar but it does the same effect than the back button.
ACTIVITY A (All these bits of code are called in OnCreate)
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String sound1name = prefs.getString("sound1", "1");
TextView sound1TV = findViewById(R.id.sound1);
sound1TV.setText(sound1Name);
ImageView sound1btn = findViewById(R.id.sound1_btn);
sound1btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent1 = new Intent(getApplicationContext(), SoundSelector.class);
startActivity(intent1);
}
});
ACTIVITY B (calls adapter)
AudioFileAdapter aFilesAdapter = new AudioFileAdapter(SoundSelector.this, audioFileList, soundID);
ListView listView = findViewById(R.id.sounds_list);
listView.setAdapter(aFilesAdapter);
ADAPTER IN ACTIVITY B (OnClickListener when text is selected)
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(contextL);
SharedPreferences.Editor editor = settings.edit();
editor.putString("sound1", sound1string);
editor.apply();
Intent intent1 = new Intent(getContext(), SoundEditor.class);
con.startActivity(intent1);
Im not sure if it is the Activity Lifecycle I have to modify, or intents, or something else but if someone could point me in the right direction I would really appreciate it, if you need any more information or code I'll post as soon as possible.
For storing and retrieving shared preferences try the following:
Storing
SharedPreferences preferences = getSharedPreferences("com.appname", Context.MODE_WORLD_WRITEABLE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("sound1", "YOUR STRING HERE");
editor.apply();
Retrieving
SharedPreferences prfs = getSharedPreferences("com.appname", Context.MODE_PRIVATE);
String soundString = prfs.getString("sound1", "");
Your intent looks fine, are you sure you're passing Activity A's name?
For your second scenario, you could store if the text view was deleted in the shared preference, so when the back button is pressed, it won't display it again in the previous activity.
Something like this
if (isDeleted.equals("Yes")) {
textView.setVisibility(View.INVISIBLE);
}
The way Activity B is navigating back to Activity A by restarting the activity in the front and not by onBackPressed() navigation. Besides if the navigation is an important component to update the string value then the recommended method would be to use startActivityForResult() and update the preference and the TextView upon onActivityResult() of Activity A
class ActivityA extends AppCompatActivity {
private static final int activityRequest = 0x22;
public static final String keyPref = "keyToSharedPrefData";
private TextView mTextView;
private boolean isHidden = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_activity);
mTextView = findViewById(R.id.someTextView);
final String textForTextView = SharedPrefUtils.getString(keyPref);
mTextView.setText(textForTextView);
final Button button = findViewById(R.id.someButton);
if (button != null) {
button.setOnClickListener((view) -> {
final Intent intent = new Intent(ActivityA.this, AcitivtyB.class);
startActivityForResult(intent, activityRequest);
});
}
final deleteButton = findViewById(R.id.delete_button);
if (deleteButton != null) {
deleteButton.setOnClickListener((view) -> {
mTextView.setText("");
isHidden = true;
});
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == activityRequest && resultCode == ActivityB.resultSuccess && data != null) {
if (data.containsKey(ActivityB.resultKey)) {
SharedPrefUtils.saveString(keyPref,
data.getString(ActivityB.resultKey, SharedPrefUtils.getString(keyPref));
if (mTextView != null) {
mTextView.setText(SharedPrefUtils.getString(keyPref));
}
}
}
if (isHidden) {
mTextView.setVisibility(View.GONE);
}
}
}
in ActivityB you can
class ActivityB extends AppCompatActivity {
public static final int resultSuccess = 0x11
public static final int resultFailure = 0x33
public static final String resultKey = "keyForResult"
private void onListItemClick(final String soundString) {
// optional you can also do this
SharedPrefUtils.saveString(ActivityA.keyPref, soundString);
// better to do this
final Intent returnIntent = getIntent() != null ? getIntent() : new Intent();
returnIntent.putExtra(resultKey, soundString);
if (getCallingActivity() != null) {
setResult(returnIntent, resultSuccess);
}
onBackPressed();
}
}

How to start another activity and start a method inside it?

As soon as the setOnClickListener executes I want to start another activity and transmit the variable cn.getID() to it. When inside the other activity I want to immidietaly start the method findlocation and give cn.getID() to it.
The method findLocation is not finished yet. The idea is, once it gets the ID of the other activities button, i can search with sqllite in my database for the place it belongs to, get longitude and latitude and tell mapcontroller focus the world map on this point.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.verladestellen);
final DB_Verladestellen db = new DB_Verladestellen(this);
List<DB_Place> placeList = db.getAllDBPlaces();
final LinearLayout layout = (LinearLayout) findViewById(R.id.verladestellen_liste);
for (final DB_Place cn : placeList) {
final LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
Button place = new Button(this);
place.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
place.setText(cn.getName());
place.setId(cn.getID());
row.addView(place);
row.setId(cn.getID());
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) place.getLayoutParams();
params.weight = 1.0f;
place.setLayoutParams(params);
place.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Here I want to call the method to start the other activity
//and transmit cn.getID().
openMap(null);
}
});
layout.addView(row);
}
}
//The method to start the other activity
public void openMap(View view) {
Intent intent = new Intent(this, UI_MainActivity.class);
startActivity(intent);
}
This is the method from inside the new activity I want to execute immidietaly after it has started:
public void findLocation(View view){
MapView map = (MapView) findViewById(R.id.map);
IMapController mapController = map.getController();
mapController.setZoom(17);
GeoPoint myLocation = new GeoPoint(PLACEHOLDER X , PLACEHOLDER Y);
mapController.animateTo(myLocation);
}
EDIT:
#Murat K. After some edits this is my whole class now:
public class UI_Verladestellen extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.verladestellen);
final DB_Verladestellen db = new DB_Verladestellen(this);
List<DB_Place> placeList = db.getAllDBPlaces();
final LinearLayout layout = (LinearLayout) findViewById(R.id.verladestellen_liste);
for (final DB_Place cn : placeList) {
final LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
Button place = new Button(this);
place.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
place.setText(cn.getName());
place.setId(cn.getID());
row.addView(place);
row.setId(cn.getID());
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) place.getLayoutParams();
params.weight = 1.0f;
place.setLayoutParams(params);
place.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openMap(cn.getID());
}
});
layout.addView(row);
}
}
public void openMap(int view) {
Intent intent = new Intent(UI_Verladestellen.this, UI_MainActivity.class);
intent.putExtra("findLocation", 1);
startActivity(intent);
}
}
And this is the getIntent of my onCreate method in UI_MainActivity:
int i = getIntent().getIntExtra("findlocation", 999);
if(i == 1){
findLocation(i);
}
As I edited into my earlier comment, i cant see where my Button-ID is recieved. At first i thought i would be my ID, but that wouldnt work, since The Button ID can be every number from 1 to n.
You can achieve this with an Intent e.g.
Intent i = new Intent(BaseActivity.this, YourSecondActivity.class);
intent.putExtra("METHOD_TO_CALL", 1);
startActivity(i);
and in your onCreate() method of the starting Activity you check for it.
#Override
public void onCreate(Bundle savedInstanceState) {
int i = getIntent().getIntExtra("METHOD_TO_CALL", 999);
if(i == 1){
callMethod(i);
}
EDIT:
//The method to start the other activity
public void openMap(View view) {
Intent intent = new Intent(this, UI_MainActivity.class);
intent.putExtra("METHOD_TO_CALL", 1); // the 1 is a example, put your ID here
startActivity(intent);
}
Step #1: Use putExtra() to add your ID value to the Intent that you use with startActivity()
Step #2: In the other activity, call getIntent() in onCreate() to retrieve the Intent used to create the activity instance. Call get...Extra() (where ... depends on the data type) to retrieve your ID value. If the ID value exists, call your findLocation() method.
It depends on how you want it to work. If you only want it to execute when the activity is created (when it starts or screen rotates) then call the method within the activities onCreate method. If you want it called whenever the user returns to that activity which can include them leaving the app and coming back to it sometime later then onResume would be a better spot for it. Calling the method from either should work as you hope though.
I also recommend looking over the Activity lifecycle as that will help you a lot in the future.

Categories

Resources