I'm trying to design a page where address are stored in recycler view -> cardview.
When the user clicks the add address button from the Activity A the user is navigated to the add address page in Activity B. Here the user can input customer name, address line 1 and address line two.
And once save button is clicked in Activity B, a cardview should be created under the add address button in the Activity A.
This design is just like the amazon mobile app add address option.
Example: If a end-user has one address(one cardview will be present) and wants to add one more address(second address). Then another cardview will be created below the existing cardview with the new address.
Actual result as of now: The second address is being populated in the first cardview.
Expected result: When user enters a new address a new cardview should be created below the existing one.
Code in the Activity A
public class ProfileManageAdressFragment extends AppCompatActivity {
RecyclerView recyclerView;
ProfileManageAddressRecyclerAdapter adapter;
ArrayList<ProfileManageAddressGetterSetter> reviews;
private Button addAddress;
private String customer_name, address_one, address_two, city, state, pincode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_profile_manage_adress);
addAddress = findViewById(R.id.addNewAddress);
addAddress.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Clicked", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ProfileManageAdressFragment.this, AddNewAddress.class);
startActivityForResult(intent, 1);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1) {
if(resultCode == RESULT_OK) {
customer_name = data.getStringExtra("customer_name");
address_one = data.getStringExtra("address_one");
address_two = data.getStringExtra("address_two");
city = data.getStringExtra("city");
state = data.getStringExtra("state");
pincode = data.getStringExtra("pincode");
reviews = new ArrayList<>();
reviews.add(new ProfileManageAddressGetterSetter(customer_name, address_one, address_two, city, state, pincode));
recyclerView = findViewById(R.id.addressRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ProfileManageAdressFragment.this));
adapter = new ProfileManageAddressRecyclerAdapter(ProfileManageAdressFragment.this, reviews);
recyclerView.setAdapter(adapter);
}
}else if(resultCode == RESULT_CANCELED) {
Toast.makeText(ProfileManageAdressFragment.this, "Cancelled", Toast.LENGTH_SHORT).show();
}
}
}
Code in Activity B
public class AddNewAddress extends AppCompatActivity {
private EditText customer_name, address_one, address_two, city, state, pincode;
private Button add_address;
private String sCustomer_name, sAddress_one, sAddress_two, sCity, sState, sPincode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_new_address);
customer_name = findViewById(R.id.customerName);
address_one = findViewById(R.id.addressOne);
address_two = findViewById(R.id.addressTwo);
add_address = findViewById(R.id.addAddress);
city = findViewById(R.id.city);
state = findViewById(R.id.state);
pincode = findViewById(R.id.pincode);
final ProfileFragment profileFragment = new ProfileFragment();
add_address.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//setFragment(profileFragment);
if(customer_name.getText().toString().equals("") || address_one.getText().toString().equals("") ||
address_two.getText().toString().equals("") || city.getText().toString().equals("") ||
state.getText().toString().equals("") || pincode.getText().toString().equals("")
) {
Toast.makeText(AddNewAddress.this, "Please input all fields", Toast.LENGTH_LONG).show();
}else {
sCustomer_name = customer_name.getText().toString();
sAddress_one = address_one.getText().toString();
sAddress_two = address_two.getText().toString();
sCity = city.getText().toString();
sState = state.getText().toString();
sPincode = pincode.getText().toString();
Intent intent = new Intent(AddNewAddress.this, ProfileManageAdressFragment.class);
intent.putExtra("customer_name", sCustomer_name);
intent.putExtra("address_one", sAddress_one);
intent.putExtra("address_two", sAddress_two);
intent.putExtra("city", sCity);
intent.putExtra("state", sState);
intent.putExtra("pincode", sPincode);
//startActivity(intent);
//startActivityForResult(intent, 1);
setResult(RESULT_OK, intent);
finish();
}
}
});
}
}
Kindly let me know if additional information is required. Million thanks in advance for solutions! :)
There are many things you have to handle
In ProfileManageAdressFragment
Naming Convention matter more extended AppCompatActivity and the class name is ProfileManageAdressFragment.
Button object created globally that not required, make it local obj.
same String customer_name and many more obj you're using inside onActivityResult so don't need to initialize globally make it local Obj.
In onActivityResult every time you reinitialize the recyclerView and adapter that not required. initialize recyclerView and adapter inside onCreate and when you get Data in onActivityResult add data to ArrayList and call adapter.notifyDataSetChange.
In onActivityResult using nested condition for request code and ResultCode make it on single condition Like. if (requestCode == 1 && resultCode == RESULT_OK){ code body }else {}
In AddNewAddress
All globally initialize objects not required it takes memory only. so make it locally if you're not using outside of the method.
Instead checking value like this customer_name.getText().toString().equals("") , android provide one class TextUtil and TextUtil has one method isEmpty use that method.
So, as I think, the problem is in this lines
reviews = new ArrayList<>();
reviews.add(new ProfileManageAddressGetterSetter(customer_name, address_one, address_two, city, state, pincode));
You're creating a new object of ArrayList with one item, instead of updating existing one. After that you're creating another object of adapter, instead of using existing one and refreshing it's data. So that's why you can't see another CardView populated.
Try add to your adapter next function:
void addItems(items: ArrayList<ProfileManageAddressGetterSetter>) {
this.items.addAll(items);
notifyDataSetChanged();
}
And when you receiving a result from ActivityB - insert it to your adapter with help of addItems(items: ArrayList<ProfileManageAddressGetterSetter>) function.
For better usage of adapter keep it's variable as global variable in your Activity class and call it whenever you need.
Related
In the code below (log in code), I have one button that if it clicked, it will start two intent. One intent is to use to open A class and the other is to use to send a string value to B class. But when the button clicked, the second intent not just sending the string value but also open the B class. The code supposedly to just send the string value to B class and open A class.
How to fix this?
package com.example.project;
public class login extends AppCompatActivity {
DatabaseReference reff;
EditText kode, pass;
Button masuk;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
FirebaseApp.initializeApp(this);
kode = (EditText)findViewById(R.id.kode);
pass = (EditText)findViewById(R.id.pass);
masuk = (Button)findViewById(R.id.masuk);
masuk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(TextUtils.isEmpty(kode.getText().toString()) || TextUtils.isEmpty(pass.getText().toString())){
Toast.makeText(login.this, "isi kode alat atau password", Toast.LENGTH_LONG).show();
}
else {
final String value = kode.getText().toString().trim();
reff = FirebaseDatabase.getInstance().getReference().child(value);
final String password = pass.getText().toString().trim();
// Read from the database
reff.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
String passin = dataSnapshot.child("pass").getValue().toString();
if (passin.equals(password)){
Intent intent = new Intent(login.this, MainActivity.class);
startActivity(intent);
Intent send = new Intent(login.this, addmember.class);
send.putExtra("kode", value);
startActivity(send);
}
else if(!passin.equals(password)){
Toast.makeText(login.this, "password salah", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
}
});
}
}
});
}
Here, you can't start activity because you are trying to start two activities at same time. This is not possible and if possible this approach is not too good. In safe side, you can use EventBus library that used for pushing event as data and subscriber that receive that data. This is the right way to do what you want here.
Here is my situation:
I have an OnCreate code like the following:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bunz = Bunz.getInstance(); //getting instance of bunz
bunz.setBunz(50);
bunz.setMoney(0);
bunz.setIncrement(1);
Button upgradeButton = (Button) findViewById(R.id.upgradeButton);
upgradeButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
Intent startIntent = new Intent(getApplicationContext(), UpgradeMenu.class);
startActivity(startIntent);
}
});
moneyCount = (TextView) findViewById(R.id.moneyCount);
bunzCount = (TextView) findViewById(R.id.bunzCount);
ImageButton bun = (ImageButton) findViewById(R.id.bun);
}
Notice how in my OnCreate code, I do 2 things; first, I initialize all the values I need:
bunz.setBunz(50);
bunz.setMoney(0);
bunz.setIncrement(1);
and then I display these values on TextViews and set up some Buttons and intents:
Button upgradeButton = (Button) findViewById(R.id.upgradeButton);
upgradeButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
Intent startIntent = new Intent(getApplicationContext(), UpgradeMenu.class);
startActivity(startIntent);
}
});
moneyCount = (TextView) findViewById(R.id.moneyCount);
bunzCount = (TextView) findViewById(R.id.bunzCount);
ImageButton bun = (ImageButton) findViewById(R.id.bun);
I'm new to Android studio, and here is the problem I'm having. I want to use onResume() to update these values in the TextView (I update them in another activity) every time I go back to this activity. However, if I move all the code in onCreate into onResume, then every time I go back to this activity, the values will be set to 50,0, and 1. I understand I could use a boolean, so that onCreate() triggers the first time the app is launched, but onResume() doesn't trigger, and then onResume() triggers after that, and simply copy and paste the second half of the onCreate code into onResume(), but that seems inefficient, and isn't how Android studio is designed to work. Can I somehow initialize the values in another location?
I have a global Bunz class that looks like the following:
public class Bunz {
private int bunz;
private int money;
private int increment;
//singleton code
private static Bunz instance;
private Bunz(){
}
public static Bunz getInstance(){
if (instance == null){
instance = new Bunz();
}
return instance;
}
public int getBunz() {
return bunz;
}
public void setBunz(int num){
bunz = num;
}
public int getMoney(){
return money;
}
public void setMoney(int num){
money = num;
}
public int getIncrement(){
return increment;
}
public void setIncrement(int num){
increment = num;
}
}
so maybe I could initialize these values here somehow?
Thanks!
here's one thing you could alternatively do:
public static Bunz getInstance(){
if (instance == null){
instance = new Bunz();
instance.setBunz(50);
instance.setMoney(0);
}
return instance;
}
in your instance creation here, try setting the values you want here, instead of in onCreate of the app.
you could just be making the changes in the constructor as well.
While your code uses statics, which I believe is unnecessary. Statics are not your average goto solution, they come with a hefty price of an object not eligible for GC.
You can get the result from the second activity via onActivityResult method.
First, start second activity using startAtivityForResult() //This takes in a request code(Int), it can be whatever you set.
First activity
Intent intent = new Intent(this, SecondActivity.class);
startActivityForResult(intent , 100);
Second Activity
//Do you work in the second activity, generate new data
Intent returnIntent = new Intent();
returnIntent.putExtra("bunz", 100);
returnIntent.putExtra("money", 200);
returnIntent.putExtra("increment", 2);
setResult(Activity.RESULT_OK, returnIntent);
finish();
Capture Second Activity Result
This code is supposed to be written in your first activity.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) { //Remember the code we set in startActivityForResult? This is where we identify our work
if(resultCode == Activity.RESULT_OK){ //Code to check if data is passed
Int bunz =data.getIntExtra("bunz")
bunz.setBunz(bunz)
.....
}
}
}
I am making an Android app, and currently have 3 different activities. One that displays 'Recent' images from Flickr in a Recyclerview, another that displays 'Interesting' images from Flickr in a Recyclerview, as well as a 'Details' activity which displays a larger image view and more information about a particular photo when it is clicked.
I have two ArrayLists: recentImageList and interestingImageList, which use the same Adapter class to display the different images and their attributes (title, owner etc.) in their Recyclerviews, depending on the activity.
I have these two activities working and showing the correct content, and when I click on a 'recent' photo, it displays the same 'recent' photo on the 'details' page.
However my problem is that when an 'interesting' image is clicked, it passes the position of the 'recent' image to the Intent instead of the position of the 'interesting' image I clicked on. Therefore this displays the 'recent' image in the 'Details' activity, and not the 'interesting' photo I clicked on.
I am unsure how to pass the correct position of the interestingImageList array item in my onClickListener, so that the correct corresponding image is shown in my 'details' activity. Do I need some sort of if statement in my OnClickListener to determine which arraylist position is passed to the intent?
I'd be grateful for any help you guys can give. See the code for my ImageListAdapter class below:
public class ImageListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
ArrayList<ImageInfo> recentImageList;
ArrayList<ImageInfo> interestingImageList;
private int whichActivity;
public ImageListAdapter(Context context, ArrayList<ImageInfo> recentImageList,
ArrayList<ImageInfo> interestingImageList, int whichView) {
this.context = context;
this.recentImageList = recentImageList;
this.interestingImageList = interestingImageList;
whichActivity = whichView;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.cell_image_card, parent, false);
return new ImageViewHolder(itemView);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
if (whichActivity == 0) {
((ImageViewHolder) viewHolder).populate(recentImageList.get(position));
ImageInfo recentInfo = recentImageList.get(position);
} else if (whichActivity == 1) {
((ImageViewHolder) viewHolder).populate(interestingImageList.get(position - recentImageList.size()));
ImageInfo interestingInfo = interestingImageList.get(position);
}
}
#Override
public int getItemCount() {
return recentImageList.size() + interestingImageList.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
public TextView imageTitle, ownerTitle, tags;
public NetworkImageView mainImage, ownerImage;
public ImageViewHolder(View itemView) {
super(itemView);
imageTitle = (TextView) itemView.findViewById(R.id.imageTitle);
ownerTitle = (TextView) itemView.findViewById(R.id.ownerTitle);
mainImage = (NetworkImageView) itemView.findViewById(R.id.mainImage);
mainImage.setOnClickListener(onClick);
ownerImage = (CircularNetworkImageView) itemView.findViewById(R.id.ownerImage);
}
public void populate(ImageInfo imageInfo) {
ownerTitle.setText(imageInfo.owner);
imageTitle.setText(imageInfo.title);
mainImage.setImageUrl(imageInfo.url_m, NetworkMgr.getInstance(context).imageLoader);
ownerImage.setImageUrl(imageInfo.ownerPic, NetworkMgr.getInstance(context).imageLoader);
}
View.OnClickListener onClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, DetailsActivity.class);
int position = ImageViewHolder.this.getLayoutPosition();
intent.putExtra("PHOTO_POSITION", position);
context.startActivity(intent);
}
};
}
}
You need two different instances of your adapter, each one for each list this seems like a wrong implementation
Each recyclerview should have its own adapter instance.
e.g.
new
ImageListAdapter(this, recentImageList, null, whichView);
and
new
ImageListAdapter(this, null , interestingImageList,whichView);
For two different RecyclerView you will need two instance of the adapter. To go to the details activity, it will be better to get the selected or clicked item position in activity and start the details activity from present activity. To get the selected position from the adapter you can use interface. Here is an open source RecyclerView-Listener library to get the selected item position. You can use it or understand the concept and implement yourself.
Thank you everyone for your help! I've fixed it!
I realised that my original code was correct, however the line in my Details Activity:
photo = NetworkMgr.getInstance(this).recentImageList.get(photoPosition);
was the problem, as this line retrieved only the position for the recent images and didn't account for the interesting images. Therefore, in my OnClickListener I used an if statement for the two whichActivitys and putExtra a number to determine which arraylist needs to have its position retrieved in Details activity. See below:
ImageListAdapter -
View.OnClickListener onClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (whichActivity == 0) {
Intent intent = new Intent(context, DetailsActivity.class);
int position = ImageViewHolder.this.getLayoutPosition();
int imageListCode = 1;
intent.putExtra("PHOTO_POSITION", position);
intent.putExtra("IMAGELIST_CODE", imageListCode);
context.startActivity(intent);
}
else if (whichActivity == 1) {
Intent intent = new Intent(context, DetailsActivity.class);
int position = ImageViewHolder.this.getLayoutPosition();
int imageListCode = 2;
intent.putExtra("PHOTO_POSITION", position);
intent.putExtra("IMAGELIST_CODE", imageListCode);
context.startActivity(intent);
}
}
};
DetailsActivity -
Intent intent = getIntent();
photoPosition = intent.getIntExtra("PHOTO_POSITION", 0);
code = intent.getIntExtra("IMAGELIST_CODE", 0);
if (code == 1) {
photo = NetworkMgr.getInstance(this).recentImageList.get(photoPosition);
}
else if (code == 2) {
photo = NetworkMgr.getInstance(this).interestingImageList.get(photoPosition);
}
I have a problem, I want to click on the list, calling a new activity and rename the button to another name.
I tried several things, nothing worked, can someone please help me?
My class EditarTimes:
private AdapterView.OnItemClickListener selecionarTime = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView arg0, View arg1, int pos, long id) {
t = times.get(pos);
CadastroTimes cad = new CadastroTimes();
CadastroTimes.salvar.setText("Alterar");
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
startActivity(intent);
}
};
public class CadastroTimes extends AppCompatActivity {
private Time t;
private timeDatabase db;
private EditText edID;
private EditText edNome;
public Button salvar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cadastro_times);
edID = (EditText) findViewById(R.id.edID);
edNome = (EditText) findViewById(R.id.edNome);
db = new timeDatabase(getApplicationContext());
salvar = (Button) findViewById(R.id.btnCadastrar);
salvar.setText("Cadastrar");
String newString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
newString= null;
} else {
newString= extras.getString("Alterar");
}
} else {
newString= (String) savedInstanceState.getSerializable("Alterar");
}
//button in CadastroTimes activity to have that String as text
System.out.println(newString + " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
salvar.setText(newString);
}
public void salvarTime(View v) {
t = new Time();
t.setNome(edNome.getText().toString());
if (salvar.getText().equals("Alterar")) {
db.atualizar(t);
exibirMensagem("Time atualizado com sucesso!");
} else {
db.salvar(t);
exibirMensagem("Time cadastrado com sucesso!");
}
Intent intent = new Intent(this, EditarTimes.class);
startActivity(intent);
}
private void limparDados() {
edID.setText("");
edNome.setText("");
edNome.requestFocus();
}
private void exibirMensagem(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
}
public class EditarTimes extends AppCompatActivity {
private Time t;
private List<Time> times;
private timeDatabase db;
private ListView lvTimes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editar_times);
lvTimes = (ListView) findViewById(R.id.lvTimes);
lvTimes.setOnItemClickListener(selecionarTime);
lvTimes.setOnItemLongClickListener(excluirTime);
times = new ArrayList<Time>();
db = new timeDatabase(getApplicationContext());
atualizarLista();
}
private void excluirTime(final int idTime) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Excluir time?")
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage("Deseja excluir esse time?")
.setCancelable(false)
.setPositiveButton(getString(R.string.sim),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (db.deletar(idTime)) {
atualizarLista();
exibirMensagem(getString(R.string.msgExclusao));
} else {
exibirMensagem(getString(R.string.msgFalhaExclusao));
}
}
})
.setNegativeButton(getString(R.string.nao),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.create();
builder.show();
atualizarLista();
}
private void atualizarLista() {
times = db.listAll();
if (times != null) {
if (times.size() > 0) {
TimeListAdapter tla = new TimeListAdapter(
getApplicationContext(), times);
lvTimes.setAdapter(tla);
}
}
}
private AdapterView.OnItemClickListener selecionarTime = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long id) {
t = times.get(pos);
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
String strName = "Alterar";
intent.putExtra("Alterar", strName);
startActivity(intent);
}
};
private AdapterView.OnItemLongClickListener excluirTime = new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int pos, long arg3) {
excluirTime(times.get(pos).getId());
return true;
}
};
private void exibirMensagem(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
public void telaCadastrar(View view) {
Intent intent = new Intent(this, CadastroTimes.class);
startActivity(intent);
}
public void botaoSair(View view) {
Intent intent = new Intent(this, TelaInicial.class);
startActivity(intent);
}
}
You can pass the button caption to CadastroTimes with intent as
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
intent.putExtra("buttontxt","Changed Text");
startActivity(intent);
Then in CadastroTimes.java set the text of the button to the new value that you passed. The code will look like:
button = (Button)findViewById(R.id.button); // This is your reference from the xml. button is my name, you might have your own id given already.
Bundle extras = getIntent().getExtras();
String value = ""; // You can do it in better and cleaner way
if (extras != null) {
value = extras.getString("buttontxt");
}
button.setText(value);
Do remember to do it in onCreate after setContentView
//From Activity
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
intent.putExtra("change_tag", "text to change");
startActivity(intent);
//To Activity
public void onCreate(..){
Button changeButton = (Button)findViewById(R.id.your_button);
// Button to set received text
Intent intent = getIntent();
if(null != intent &&
!TextUtils.isEmpty(intent.getStringExtra("change_tag"))) {
String changeText = intent.getStringExtra("change_tag");
// Extracting sent text from intent
changeButton.setText(changeText);
// Setting received text on Button
}
}
1: Use intent.putExtra() to share a value from one activity another activity, as:
In ActivityOne.class :
startActivity(
Intent(
applicationContext,
ActivityTwo::class.java
).putExtra(
"key",
"value"
)
)
In ActivityTwo.class :
var value = ""
if (intent.hasExtra("key")
value = intent.getStringExtra("key")
2: Modify button text programatically as:
btn_object.text = value
Hope this will help you
For changing the button text:
Use a static method to call from the other activity to directly modify the button caption.
Use an intent functionality, which is preferable.
Use an Interface and implement it, which is used for communicating between activities or fragment in a manner of fire and forget principle.
Now, i got you:
Your EditarTimes activity with listview:
//set setOnItemClickListener
youtListView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
Intent i = new Intent(EditarTimes.this, CadastroTimes.class);
//text which you want to display on the button to CadastroTimes activity
String strName = "hello button";
i.putExtra("STRING_I_NEED", strName);
}
});
In CadastroTimes activity,
under onCreate() method, get the text string as:-
String newString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
newString= null;
} else {
newString= extras.getString("STRING_I_NEED");
}
} else {
newString= (String) savedInstanceState.getSerializable("STRING_I_NEED");
}
//button in CadastroTimes activity to have that String as text
yourButton.setText(newString);
Ok, so the first step would be to take the button you want and make it a public static object (and put it at the top of the class).
public static Button button;
Then you can manipulate that using this in another class:
ClassName.button.setText("My Button");
In your case it is
CadastroTimes.salvar.setText("Alterar");
if you want to change value from that do not do not go the activity via intent you can use file to save value to file or you have multiple values the use database and access
the value oncreate to set the value of text....
In my case, I had to send an EditText value from a Dialog styled Activity, which then got retrieved from a Service.. My Example is similar to some of the above answers, which are also viable.
TimerActivity.class
public void buttonClick_timerOK(View view) {
// Identify the (EditText) for reference:
EditText editText_timerValue;
editText_timerValue = (EditText) findViewById(R.id.et_timerValue);
// Required 'if' statement (to avoid NullPointerException):
if (editText_timerValue != null) {
// Continue with Button code..
// Convert value of the (EditText) to a (String)
String string_timerValue;
string_timerValue = editText_timerValue.getText().toString();
// Declare Intent for starting the Service
Intent intent = new Intent(this, TimerService.class);
// Add Intent-Extras as data from (EditText)
intent.putExtra("TIMER_VALUE", string_timerValue);
// Start Service
startService(intent);
// Close current Activity
finish();
} else {
Toast.makeText(TimerActivity.this, "Please enter a Value!", Toast.LENGTH_LONG).show();
}
}
And then inside my Service class, I retrieved the value, and use it inside onStartCommand.
TimerService.class
// Retrieve the user-data from (EditText) in TimerActivity
intent.getStringExtra("TIMER_VALUE"); // IS THIS NEEDED, SINCE ITS ASSIGNED TO A STRING BELOW TOO?
// Assign a String value to the (EditText) value you retrieved..
String timerValue;
timerValue = intent.getStringExtra("TIMER_VALUE");
// You can also convert the String to an int, if needed.
// Now you can reference "timerValue" for the value anywhere in the class you choose.
Hopefully my contribution helps!
Happy coding!
Accessing view reference of another Activity is a bad practice. Because there is no guarantee if the reference is still around by the time you access it (considering the null reference risk).
What you need to do is to make your other Activity read values (which you want to display) from a data source (e.g. persistence storage or shared preferences), and the other Activity manipulates these values. So it appears as if it changes the value of another activity, but in reality it takes values from a data source.
Using SharedPreferences:
Note: SharedPreferences saves data in the app if you close it but it will be lost when it has been deleted.
In EditarTimes.java:
private AdapterView.OnItemClickListener selecionarTime = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView arg0, View arg1, int pos, long id) {
t = times.get(pos);
SharedPreferences.Editor editor = getSharedPreferences("DATA", MODE_PRIVATE).edit();
editor.putString("btnText", "Your desired text");
editor.apply();
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
startActivity(intent);
}
};
In CadastroTimes.java
public Button salvar;
salvar.setText(getSharedPreferences("DATA", MODE_PRIVATE).getString("btnText", ""));
//note that default value should be blank
As far as my thoughts go, I can realize that the problem is not with the code you provided as it seems to be implemented correctly. It is possible that you have saved the activityState somewhere in your actual code and because it is not implemented properly, the savedInstanceState found in the onCreate method is not null but the required information is missing or not correct. That's why newString is getting null and salvar textview is getting blank.
Here, I need to know which one is more useful to you - information from getIntent() or from savedInstanceState? The code you provided insists me to assume that savedInstanceState has got the preference.
If you prefer savedInstanceState, then you may use SharedPreferences like this to get the same value you want:
private SharedPreferences mPrefs;
private String newString;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
........
// try to get the value of alterarValue from preference
mPrefs = getSharedPreferences("MyData", MODE_PRIVATE);
newString = mPrefs.getString("alterarValue", "");
if (newString.equals("")){
// we have not received the value
// move forward to get it from bundle
newString = getIntent().getStringExtra("Alterar");
}
// now show it in salvar
salvar.setText(newString);
}
protected void onPause() {
super.onPause();
// you may save activity state or other info in this way
SharedPreferences.Editor ed = mPrefs.edit();
ed.putString("alterarValue", newString);
ed.commit();
}
Or if you don't need to get it from savedInstanceState, please use it:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
........
// try to get the value of alterarValue from bundle
String newString = getIntent().getStringExtra("Alterar");
// now show it in salvar
salvar.setText(newString);
}
That's all I know. Hope it will help. If anything goes wrong, please let me know.
I am creating a simple note-taking app for my independent study. The problem is that any time the app is exited, the notes created are deleted and the app is completely reset. I have read several tutorials of preferences and the saveoninstance methods, but no matter how many different ways I try to implement them, I can't seem to figure it out.
public class Home extends Activity {
//Declaration of variables
private Button mNoteButton;
private String mText;
private ListView myList;
private int index;
public static final String TAG = Note.class.getSimpleName();
ArrayList<String> myArrayList= new ArrayList<String>();
ArrayAdapter<String> myAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//Setting the list item to blank
if (mText == null) {
mText = "";
}
Log.d(TAG, mText);
//creating adapter to insert myListArray into the ListView
myAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,myArrayList);
//Setting the adapter to myArrayList
myList= (ListView) findViewById(R.id.noteList);
myList.setAdapter(myAdapter);
//Creating and setting the new note button
mNoteButton = (Button)findViewById(R.id.newNoteButton);
//When button is clicked
mNoteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newNote();
}
});
//When an item in the list is clicked
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Taking the data in the item selected and sending it to the EditNote.java
index = position;
//Selecting item data
String old = myArrayList.get(index);
Intent intent = new Intent(Home.this, EditNote.class);
intent.putExtra("note_text", old);
startActivityForResult(intent, 1);
}
});
}
private void newNote()
{
//Starts and sends data to Note.java and creates a new note
Intent intent = new Intent(this, Note.class);
startActivityForResult(intent, 0);
}
protected void onActivityResult(int requestCode, int resultCode, Intent DATA) {
super.onActivityResult(requestCode, resultCode, DATA);
//Data from the Note activity is received
if (requestCode == 1 && resultCode == RESULT_OK)
{
//Gets data and saves it to myListArray as new edit
Bundle save = DATA.getExtras();
String extra = save.getString("note");
myArrayList.set(index, extra);
myList.setAdapter(myAdapter);
}
if (requestCode == 0 && resultCode == RESULT_OK) {
//Gets data and saves it to myListArray as new note
Bundle pack = DATA.getExtras();
String pageText = pack.getString("note");
myArrayList.add(pageText);
myList.setAdapter(myAdapter);
}
This is the code without saving the collected strings. Can someone please help me figure out how to implement one of the methods to save this data so it can be retrieved after the app is destroyed?
One option is to write the string as a file to internal storage:
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
String FILENAME = "yourFileName";
String extra = save.getString("note");
FileOutputStream fileOutputStream = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fileOutputStream.write(extra.getBytes());
fileOutputStream.close();
Also of course you are going to have to read in the file when you open your app, in order to set any notes that were previously saved:
Call openFileInput() and pass it the name of the file to read. This returns a FileInputStream.
Read bytes from the file with read().
Then close the stream with close().
You might find this info helpful on converting a fileInputStream to a string:
How to convert FileInputStream into string in java?