I have two fragment.In first one is EditText witch taking some info from user,and in another fragment having Spinner.I am sending EditText,that was first converted to String, to Spinner in second fragment with Android Navigation.And it shows text just fine but when i wish to add another text to Spinner it just replace first text and showing only one text/item in spinner. So my question how to have save text that i previously sent and have nice drop down spinner. BTW i am using data binding i don't know if it is important information for solutions.
fragment from where i am sending data:
#Override
public void onClickComplete() {
String addCategoryString = addCategory.getText().toString();
FluctuatingCategoryFragmentDirections.ActionFluctuatingCategoryToCreatingBudgetingItem2 action
= FluctuatingCategoryFragmentDirections.actionFluctuatingCategoryToCreatingBudgetingItem2();
action.setFluctuatingCategory(addCategoryString);
navController.navigate(action);
}
receiving fragment:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getArguments() != null) {
CreatingBudgetingItemFragmentArgs args = CreatingBudgetingItemFragmentArgs.fromBundle(getArguments());
String getCategory = args.getFluctuatingCategory();
Log.i("Category: ", getCategory);
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, android.R.id.text1);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerAdapter);
spinnerAdapter.notifyDataSetChanged();
}
}
When you are navigating to FluctuatingCategoryToCreatingBudgetingItem, the fragment is getting recreated every time, that's why only the value you passed will show up. You must use ViewModel.
Setup a list which will contain the FluctuatingCategoryies and setup your CreatingBudgetingItemFragment to get list item from ViewModel.
Not giving you any code because I want you to start your learning curve. This
might help.
Related
I'm using AppCompatSpinner with the ArrayAdapter. The data of the arrayAdapter is coming from room db and wrapped into livedata in ViewModel class.
Everything is working fine but when i navigate to other fragment and come back to Spinner fragment, the selection state is gone (and it set to selection = 0).
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(InquiryViewModel.class);
mViewModel.getItemLiveData().observe(getViewLifecycleOwner(), items -> {
dropdownItemArrayAdapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, items);
dropdownItemArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
itemType.setAdapter(dropdownItemArrayAdapter);
});
}
I have four swipeable fragments on an activity in tabbed view mode.Each fragment should show JSON data from an API.
There are two problems
The first problem is that only in first fragment I am able to get the data.
And the second problem is that when swiping to next fragment I lost the data received in the first fragment.
I have four layouts for each of the fragment.
I am using custom listview to show the data.
*After creating fragment and getting theJSON data I am using custom list view to show it in the first fragment using aeroFirst method as below but I am not able to do the same in the other fragment. Creating fragments,JSON parsing and aeroFirst method are all in MainActivityclass *
snip of the code
private void aeroFirst(List<Details> mList) {
// layout = (LinearLayout) findViewById(R.id.linear);
for (Details bean : details) {
final String urlChar = bean.getUrl();
if (bean.getResType().equals("Videos"))
{
ListView listView = (ListView) findViewById(R.id.list);
CustomListViewAdapter adapter = new CustomListViewAdapter(this,
R.layout.list_item, mList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
"Click ListItem Number " + urlChar, Toast.LENGTH_SHORT)
.show();
There must be an activity behind all four fragments, right? Store the values in that activity so that all four fragments can access the JSONs. This might not be the best in style, but the other solution involves saving it into shared preference or similar approach.
Another way to do this is to load everything in the activity, and then put the JSONs into arguments as bundles for each fragment.
Here's my situation, I have 1 Activity, and 2 Fragments. When the Activity is started it loads a Fragment, let's call it list, into the view (in a FrameLayout filling the screen). List simply lists blogs posts which are retreived via an async HTTP call to out web api. When a blog is clicked in list is runs this method in the Activity
public void loadBlog(FragmentBlog.Blog theBlog) {
blog = theBlog;
FragmentBlogDetails d = new FragmentBlogDetails();
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_BLOG, theBlog);
d.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.container, d).addToBackStack("Detail").commit();
}
Then the blog loads up and is displayed fine. Now, once I press the back key, my list Fragment calls onCreateView again and I have to run the async call again to populate my list, which reset the scroll to the top too. How can I keep my data for needing to be fetched again, and keep the view so the scroll stays where it is?
Here's my onCreateView method in the list Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d("FragmentBlog", "onCreateView");
View view = inflater.inflate(R.layout.fragment_blog, container, false);
list = (ListView) view.findViewById(R.id.the_list);
list.setOnItemClickListener(this);
if (baa != null) {
list.setAdapter(baa);
}
text = (TextView) view.findViewById(R.id.my_text_view);
pb = (ProgressBar) view.findViewById(R.id.progressBar);
asyncForBlogs();
return view;
}
If you need any other bits of code let me know and I'll post them.
You need to save index of last item user clicked. Define a index variable in your fragment and when users clicked on an item store item index in it. Then save data in onSaveInstanceState Call back. You can save other data like this. But make sure the data you put inside bundle is not so big. Do not put any images or videos here!
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt("index",index);
super.onSaveInstanceState(outState);
}
after saving your data you can access it in onCreate method. like this
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
index = savedInstanceState.getInt("index");
listView.smoothScrollToPosition(index);
}
}
smoothScrollToPosition scroll your list view to the last place you were been.
I am trying to make an edit feature for my todo list app. What I want to do is to tap an item on the list and then I would be sent to the new page where I can edit the item on my list. I am currently getting a warning :
This text field does not specify an inputType or a hint
Issue: Looks for text fields missing inputType or hint settings
Id: TextFields
I was wondering how can I pass the text in my ListView to my second activity as the first thing to be edited in my EditText?
This is what I have so far:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_do);
etNewItem = (EditText) findViewById(R.id.etNewItem);
lvItems = (ListView) findViewById(R.id.lvItems); // now we have access to ListView
readItems(); // read items from file
todoAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems); //create adapter
lvItems.setAdapter(todoAdapter); // populate listview using the adapter
setupListViewListener();
setupEditItemListener();
}
private void launchEditItem() {
Intent i = new Intent(this, EditItemActivity.class);
startActivity(i);
}
private void setupEditItemListener() { // on click, run this function to display edit page
lvItems.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
launchEditItem();
}
});
}
I can't tell from what you have posted what exactly you are trying to pass. However, there are several things you can do.
(1) You can put a reference to your ListView in a subclass of Application. Application is a good place to put application-scope global variables.
(2) Similar to (1), put a reference to the adapter in your Application subclass.
(3) You can pass the query or other list setup parameters to the edit activity and let it requery.
(4) You can pass the index or other key info from the selected list item using putExtra() to the intent. You can pass updated info back to the main activity by passing back an intent. The main activity will receive the returned intent if it uses StartActivityWithResult().
Here is my scenario:
I have a MainActivity and a CustomListViewActivity. In my MainActivity, I have 1 button and 1 spinner. On click of the button, I pass the selected spinner value to the CustomListViewActivity via Bundle and using Intents.
Now, in my CustomListViewActivity, I have a ListView that uses ArrayAdapter for populating it. I send a ArrayList from MainActivity, say for example
items = [abc]
In my CustomListViewActivity, I receive the same and use it to populate my ListView. The first time I do this, my value gets populated. The second time I do the same, the value existing is now replaced with the new one and the ListView shows one item instead of showing two.
So basically the problem is that the ListView is not updating and not showing both the items. Instead it shows me a single item always.
Here are snippets of my code
MainActivity.java
//code inside button click
..
{
items.add(spinner1.getSelectedItem().toString());
Bundle bundle =new Bundle();
bundle.putStringArrayList("data",items);
Intent i = new Intent(MainActivity.this,MyListViewActivity.class);
i.putExtras(bundle);
startActivity(i);
finish();
}
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
Log.i("App","onSave");
icicle.putStringArrayList("data",items);
}
#Override
protected void onRestoreInstanceState(Bundle icicle2) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(icicle2);
Log.i("App","onRestore");
icicle2.putStringArrayList("data",items);
}
MyListViewActivity.java
private ArrayList<String> myItems;
private static String[] titles;
CustomListViewAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
listView = (ListView) findViewById(R.id.list1);
rowItems = new ArrayList<RowItem>();
adapter = new CustomListViewAdapter(this,R.layout.list_item, rowItems);
listView.setAdapter(adapter);
b=getIntent().getExtras();
if(b!=null)
{
myItems=b.getStringArrayList("data");
titles= new String[myItems.size()];
titles = myItems.toArray(myItems);
}
...
int i=0;
while(i<titles.length) {
item = new RowItem(titles[i]);
//rowItems.add(item);
Log.i("ROW", ""+rowItems.size());
i++;
adapter.add(item);
listView.setAdapter(adapter);
}
adapter.setNotifyOnChange(true);
adapter.notifyDataSetChanged();
}
}
How to make the ListView maintain the current data as well reflect the added data?
Thanks in advance
EDIT : Forgot to mention one more thing. In my MyListViewActivity class I have a button above the ListView that on clicked takes me to my MainActivity so that I can add a new Item again. So when I go back to MainActivity and try and add a new Item , it's the new Item that get displayed rather than showing both the previous and the new one
You need to persist and restore your items list in MainActivity's onSaveInstanceState and onRestoreInstanceState methods.
You also probably don't need to close the MainActivity by calling finish() every time you start the ListView activity but that depends on your application.
Basically, the problem you are having is that items is being recreated with each new instance of MainActivity. Since you finish MainActivity, a new instance is used every time you access that activity (and I assume you thought that items would just keep getting items added to it).