Hello how do I select a specific data in a list?
I have this list
for example I clicked on Kaiser (which is not in first nor last in the list)
I set this on the fragment
name.setText(obj.getName());
but the one that shows up is Mogul (which is the last on the list)
so how do I select the name specifically? any ideas?
edit:
here's the fragment and adapter
public class LivestockDetailFragment extends Fragment {
private Livestock livestock;
private View view;
private ImageButton pencil;
private EditText name;
private ImageButton save;
public static LivestockDetailFragment newInstance(Livestock livestock) {
LivestockDetailFragment fragment = new LivestockDetailFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(DVBoerConstants.DV_LIVESTOCK_EXTRA, livestock);
fragment.setArguments(bundle);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment_packages
view = inflater.inflate(R.layout.fragment_livestock_detail, container, false);
livestock = (Livestock) getArguments().getSerializable(DVBoerConstants.DV_LIVESTOCK_EXTRA);
//initLivestockDetailsView(view);
initializeEdit();
ViewPager pager = (ViewPager) view.findViewById(R.id.viewPager);
pager.setAdapter(new MyPagerAdapter(getActivity().getSupportFragmentManager()));
name.setText(livestock.getName());
return view;
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return LivestockDetailPageFragment.newInstance(livestock);
case 1: return LivestockMedicalHistoryPageFragment.newInstance(livestock);
case 2: return LivestockGalleryPageFragment.newInstance(livestock);
default: return LivestockDetailPageFragment.newInstance(livestock);
}
}
#Override
public int getCount() {
return 3;
}
private String tabtitles[] = new String[]{"Details", "Medical History", "Gallery"};
Context context;
#Override
public CharSequence getPageTitle(int position) {
return tabtitles[position];
}
}
/*RecyclerView recyclerView = (RecyclerView)view.findViewById(R.id.livestock_detail_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(),1);
recyclerView.setLayoutManager(layoutManager);
LivestockDetailAdapter adapter = new LivestockDetailAdapter(getActivity(), livestock);
recyclerView.setAdapter(adapter);*/
private void initializeEdit(){
pencil = (ImageButton) view.findViewById(R.id.editName);
name = (EditText) view.findViewById(R.id.nameTextView);
save = (ImageButton) view.findViewById(R.id.saveName);
save.setOnClickListener(buttonList);
pencil.setOnClickListener(buttonList);
}
private View.OnClickListener buttonList = new View.OnClickListener(){
public void onClick(View view) {
switch (view.getId()){
case R.id.editName:
save.setVisibility(View.VISIBLE);
name.setFocusableInTouchMode(true);
KeyboardUtility.openKeyboard(getActivity());
pencil.setVisibility(View.INVISIBLE);
break;
case R.id.saveName:
pencil.setVisibility(View.VISIBLE);
name.setFocusableInTouchMode(false);
name.setFocusable(false);
save.setVisibility(View.INVISIBLE);
KeyboardCloseUtility.hideKeyboard(getActivity());
break;
}
}
};
}
for every list, there's an index and you can get your specific item from index list. In your case you can also get the position from that list.
Based on your comment i guess you are not creating new object everytime .. if you are looping through array put Object generation code inside of loop. if thats not the case i cant help without looking at code
Looking at you problem, there can be two problems that I can see.:
you are not initializing your obj every time before adding it to the List.
Example: List<Object> lst= new ArrayList<Object>();
Object obj = new Object();
obj.setParam();
list.add();
obj.setparam();
list.add();
In this example before every setParam() you must do obj = new Object();
Otherwise every time you will be setting same Param to all the obj and
that param will be none other than the last one. So every list.add();
will add same object to the list.
you added obj outside of a loop in which you are setting the parameters
(all the names) so it will add only the last object to the list.
example:Object obj =null;
while(some condition is true){
obj = new object();
obj.setParam();
}
lst.add(obj);
In this example you might initialize obj every time but you are adding
only last obj to the list. Here you will have to put lst.add(obj);
inside the loop.
I hope your case is among these only.
Related
I am learning RecyclerView in MVVM pattern from a youtube video. I create a recycler view to load very simple items. It works fine, but when I navigate to a new activity and then come back to the activity using Recycler View. My items in the list is duplicated. For example, my recycler view shows 2 items like Item1 and Item2. After I move to a new activity and return back, the list become Item1, Item 2, Item1 and Item2. So, each time I move to the new activity and return back, it keep doubling more and more. I only want the recycler view load one time, how can I solve this problem? Thank you.
My repo:
public class DWCategoryRepository {
private static DWCategoryRepository instance;
private ArrayList<DWCategories> dataSet = new ArrayList<>();
public static DWCategoryRepository getInstance() {
if (instance == null){
instance = new DWCategoryRepository();
}
return instance;
}
public MutableLiveData<List<DWCategories>> getDWCategories(){
setDWCategories();
MutableLiveData<List<DWCategories>> data = new MutableLiveData<>();
data.setValue(dataSet);
return data;
}
private void setDWCategories() {
dataSet.add(new DWCategories("Item1"));
dataSet.add(new DWCategories("Item2"));
}
}
My ViewModel:
public class MainWalletViewModel extends ViewModel {
private MutableLiveData<List<DWCategories>> mCategories;
private DWCategoryRepository mRepo;
public void init(){
if (mCategories != null) {
return;
}
mRepo = DWCategoryRepository.getInstance();
mCategories = mRepo.getDWCategories();
}
public LiveData<List<DWCategories>> getDWCategories(){
return mCategories;
}
}
View:
public class MainWalletActivity extends DWBaseActivity implements WalletCategoryAdapter.OnCategoryListener {
private WalletCategoryAdapter mWalletCategoryAdapter;
private MainWalletViewModel mMainWalletViewModel;
private RecyclerView mRecyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeDataBinding();
}
private void initializeDataBinding() {
MainWalletActivityBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.main_wallet_activity);
setSupportActionBar(dataBinding.walletToolbar);
//Enable Back button on Toolbar
showBackArrowOnToolbar();
//Get Categories from View Model
initCategories();
//Set up adapter
mWalletCategoryAdapter = new WalletCategoryAdapter(this, mMainWalletViewModel.getDWCategories().getValue(), this);
//Set adapter to Recycler view
mRecyclerView = dataBinding.walletCategoryRV;
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(mWalletCategoryAdapter);
//Add divider to Recycler view
mRecyclerView.addItemDecoration(new DividerItemDecoration(MainWalletActivity.this,
DividerItemDecoration.VERTICAL));
}
private void initCategories(){
mMainWalletViewModel = ViewModelProviders.of(this).get(MainWalletViewModel.class);
mMainWalletViewModel.init();
mMainWalletViewModel.getDWCategories().observe(this, new Observer<List<DWCategories>>() {
#Override
public void onChanged(#Nullable List<DWCategories> dwCategories) {
mWalletCategoryAdapter.notifyDataSetChanged();
}
});
}
}
You are calling setDWCategories in your getter.
public MutableLiveData<List<DWCategories>> getDWCategories(){
setDWCategories(); // <- Remove this line!
MutableLiveData<List<DWCategories>> data = new MutableLiveData<>();
data.setValue(dataSet);
return data;
}
You should only initialize your repo data once. Maybe do it in your getInstance() method if you are ok, starting over every time you run the app.
What I want to do is to show the same selected items on a recycler view even after the activity has been closed and only change items color when I again click on it. For now I have achieved changing the color on click but the state doesn't get saved?
This is my adapter:
public class LightsRecyclerViewAdapter extends
RecyclerView.Adapter<LightsRecyclerViewAdapter.ViewHolder> {
// private List<Integer> mViewColors;
private List<String> mAnimals;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
LightsRecyclerViewAdapter(Context context, List<String>
animals) {
this.mInflater = LayoutInflater.from(context);
this.mAnimals = animals;
}
// inflates the row layout from xml when needed
#Override
#NonNull
public ViewHolder onCreateViewHolder(#NonNull ViewGroup
parent, int viewType) {
View view = mInflater.inflate(R.layout.item, parent,
false);
return new ViewHolder(view);
}
// binds the data to the view and textview in each row
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int
position) {
// int color = mViewColors.get(position);
String animal = mAnimals.get(position);
// holder.myView.setBackgroundColor(color);
holder.myTextView.setText(animal);
}
// total number of rows
#Override
public int getItemCount() {
return mAnimals.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
View myView;
TextView myTextView;
ViewHolder(View itemView) {
super(itemView);
// myView = itemView.findViewById(R.id.colorView);
myTextView =
itemView.findViewById(R.id.tvAnimalName);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null)
mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
public String getItem(int id) {
return mAnimals.get(id);
}
// allows clicks events to be caught
public void setClickListener(ItemClickListener
itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
And this is my activity:
public class DevicesList extends AppCompatActivity implements
LightsRecyclerViewAdapter.ItemClickListener{
private LightsRecyclerViewAdapter adapter,adapter1;
TextView title;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_devices_list);
title = (TextView)findViewById(R.id.textGrid);
// data to populate the RecyclerView with
ArrayList<Integer> viewColors = new ArrayList<>();
viewColors.add(Color.BLUE);
viewColors.add(Color.YELLOW);
viewColors.add(Color.MAGENTA);
viewColors.add(Color.RED);
viewColors.add(Color.BLACK);
ArrayList<String> Lab1LightsList = new ArrayList<>();
Lab1LightsList.add("Light 1");
Lab1LightsList.add("Light 2");
Lab1LightsList.add("Light 3");
Lab1LightsList.add("Light 4");
Lab1LightsList.add("Light 5");
ArrayList<String> Lab1ACList = new ArrayList<>();
Lab1ACList.add("AC 1");
Lab1ACList.add("AC 2");
Lab1ACList.add("AC 3");
Lab1ACList.add("AC 4");
Lab1ACList.add("AC 5");
ArrayList<String> Lab2LightsList = new ArrayList<>();
Lab2LightsList.add("Light 1");
Lab2LightsList.add("Light 2");
Lab2LightsList.add("Light 3");
Lab2LightsList.add("Light 4");
Lab2LightsList.add("Light 5");
Lab2LightsList.add("Light 6");
ArrayList<String> Lab2ACList = new ArrayList<>();
Lab2ACList.add("AC 1");
Lab2ACList.add("AC 2");
Lab2ACList.add("AC 3");
Lab2ACList.add("AC 4");
// set up the RecyclerView
RecyclerView recyclerView = findViewById(R.id.list1);
RecyclerView recyclerView1 =findViewById(R.id.list2);
LinearLayoutManager horizontalLayoutManagaer
= new LinearLayoutManager(DevicesList.this, LinearLayoutManager.HORIZONTAL, false);
LinearLayoutManager horizontalLayoutManager
= new LinearLayoutManager(DevicesList.this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(horizontalLayoutManagaer);
recyclerView1.setLayoutManager(horizontalLayoutManager);
Intent mIntent = getIntent();
int intValue = mIntent.getIntExtra("labno", 0);
if(intValue==0) {
adapter = new LightsRecyclerViewAdapter(this, Lab1LightsList);
adapter1 = new LightsRecyclerViewAdapter(this, Lab1ACList);
adapter.setClickListener(this);
adapter1.setClickListener(this);
recyclerView.setAdapter(adapter);
recyclerView1.setAdapter(adapter1);
}
if(intValue==1) {
adapter = new LightsRecyclerViewAdapter(this, Lab2LightsList);
adapter1 = new LightsRecyclerViewAdapter(this, Lab2ACList);
adapter.setClickListener(this);
adapter1.setClickListener(this);
recyclerView.setAdapter(adapter);
recyclerView1.setAdapter(adapter1);
}
}
#Override
public void onItemClick(View view, int position) {
Toast.makeText(this, "You clicked " +
adapter.getItem(position) + " on item position " + position,
Toast.LENGTH_SHORT).show();
view.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
}
}
Please help on this.
Create one selected item position list and store it in prefs when an app goes to background or closed. Load that list when launching an app and compare that list in an adapter's onBindViewHolder's position parameter and marks it selected/unselected based on a comparison.
As per my understandings about your question, you want to save the state of the selected items even after the app is closed, and then you want to reload it whenever the app is launched again. You need to refer to this link Android Save Data
For the above solution, there can be various ways to save state, I am mentioning a few below:
Use SQLite Database to save the selected items. Then, whenever the app is loaded, fetch all the selected data from the DB and then mark them selected with whatever colour you want on the list.
You can also use Shared Preferences, to store the selection. And, same as above, you can reload the data when the app is launched.
You can also store the data in a specific format, maybe CSV, JSON, XML etc., in a file and save it either in Internal Storage or External Storage of the device. And when the app is launched, fetch all the selected values from the file and process accordingly.
You can also use a web server, Firebase Storage, or other cloud storage services to save the data and then fetch the data on new app launch.
Do note: All these techniques require you to save the state before the app is closed. So it is better to store the states, either on click of the item, or onPause method of the activity.
If you face any problems with these solutions, you can post another comment and I will give it a look.
Save these clicked item position in a hashmap in Shareprefence. suppose u close the activity after u coming back the activity just pass the saved list with ur data in adapter and compare the shareprefence list with ur data list if position or data match than make the itemview layout colored.
// save clicked item is a list and save it sharePreference.
List<Integer> clikedList = new ArrayList<>();
if (clicked item){
ClikedList.add(position)
}
String value = gson.toJson(list);
SharedPreferences prefs = context.getSharedPreferences("mylist",
Context.MODE_PRIVATE);
Editor e = prefs.edit();
e.putString("list", value);
e.commit();
// for getting cliked position list from SharePreference
SharedPreferences prefs = context.getSharedPreferences("mylist",
Context.MODE_PRIVATE);
String value = prefs.getString("list", null);
GsonBuilder gsonb = new GsonBuilder();
Gson gson = gsonb.create();
MyObject[] list = gson.fromJson(value, MyObject[].class);
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// suppose clicked position 4 u get from shaved cliked list
in here u neddd to retreive cliked list position and clored those item
int select = 4;
if (select == position) {
holder.itemView.setBackgroundColor(Color.BLUE);
Toast.makeText(context, "" + position, Toast.LENGTH_SHORT).show();
} else {
holder.itemView.setBackgroundColor(Color.parseColor("#214F4B"));
Toast.makeText(context, "" + position, Toast.LENGTH_SHORT).show();
}
holder.tv_title.setText(data.get(position));
}
Question from Noob android developer
Issue Defitition :
I'm trying to achieve endless scrolling implement functionality of loading more data via network request when the FragmentStatePagerAdapter reaches last item, currently i'm setting static number for getCount to 10//, what i'd like to do is trigger a network request as soon as it hits 7th item to get 10 more items and refresh the list, keeping the cycle going and potentially end up with more than 100 items hence why i'm using FragmentStatePagerAdapter, also store/cache the data so to support left to right & right to left swipe
Here's what i've tried so far
Read this article infinite viewpager however it only works for
limited set of fragments perhaps a static number, what i'm trying to
do is more dynamic as such I dont have a fixed getCount.
Read the article endless scrolling adapters, i'm not trying to use
recycler view as viewpager works just fine for what i'm trying to do
Few more pageradapter implementations
what i've learnt so far
need to override getcount to return the maximum possible value
public int getCount() {
#Override
return Integer.MAX_VALUE;
}
*I'm not sure if should also override getItemPosition or implement some kind on pageListener there are many examples available online using pagerAdapter/fragmentPageradapter i'm getting confused as to which ones are related to FragmentStatePagerAdapter and which ones are not
*
// My Framgent class
public class ScreenSlidePageFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.activity_screen_slide_page_fragment,container,false);
return rootView;
}
public static ScreenSlidePageFragment newInstance (String url){
ScreenSlidePageFragment newFragment = new ScreenSlidePageFragment();
Bundle args = new Bundle();
args.putString("imagePathUrl", url);
newFragment.setArguments(args);
return newFragment;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ImageView mImageView = (ImageView) getView().findViewById(R.id.imageView);
String imageUrl = getArguments().getString("imagePathUrl");
if (imageUrl==null){
Log.i("ScreenSlidePageFragment","no data passed");
}else {
Glide.with(this).load(imageUrl).into(mImageView);
}
}
}
// My adapter implementation
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
List<Resource> mResources;
String url;
Context mContext;
private int NUM_PAGES = 5;
private int currentPosition = 0;
public ScreenSlidePagerAdapter(FragmentManager fm, List<Resource> res,
Context context) {
super(fm);
mResources = res;
mContext = context;
}
#Override
public Fragment getItem(int position) {
if (mResources != null & mResources.size() > 0){
url = mResources.get(position).getUrl();
Log.i("url",url);
return ScreenSlidePageFragment.newInstance(url);
}else {
Toast.makeText(mContext,"no results returned",Toast.LENGTH_LONG).show();
return null;
}
}
#Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
any help will be highly appreciated
Use FragmentStatePagerAdapter (support.v13) and implement getItemPosition like this:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
https://hedgehogjim.wordpress.com/2013/10/03/android-updatable-swipe-navigation-with-fragmentstatepageradapter/
return POSITION_NONE "Causes adapter to reload all Fragments when notifyDataSetChanged is called"
Add a OnPageChangeListener to your ViewPager and load more data after comparing the given position value with your current data size
#Override
public void onPageSelected(int position) {
//Load previous data set if position == 0
//Load next data set if position == myAdapter.mResources.size() - 1
}
After the new data set has been loaded (and sorted), call myAdapter.notifyDataSetChanged() then calculate and set the new index to match the old offset so the user don't see any shift
myViewPager.setCurrentItem(myNewIndex, false)
Note: Sorting and new index calculation is only necessary when loading a previous data set.
I`ve got an activity with ViewPager. There is 1 Fragment class - ScheduleFragment and a BroadcastReceiver in it. What I need is to get info and fill up the list in the fragment, based on its position.
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
ScheduleFragment scheduleFragment = new ScheduleFragment();
return scheduleFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 5 total pages.
return 5;
}
#Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.descr_monday);
case 1:
return getString(R.string.descr_tuesday);
case 2:
return getString(R.string.descr_wednesday);
case 3:
return getString(R.string.descr_thursday);
case 4:
return getString(R.string.descr_friday);
}
return null;
}
And here the ScheduleFragment`s methods:
public ScheduleFragment newInstance(Integer day) {
ScheduleFragment fragment = new ScheduleFragment();
Bundle args = new Bundle();
args.putInt("day", day);
fragment.setArguments(args);
return fragment;
}
private class ScheduleBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ArrayList<Lesson> result = (ArrayList<Lesson>) intent.getSerializableExtra("schedule");
ArrayList<Lesson> dataToInsert = new ArrayList<>();
Log.i("ASSSSSSSSSSSS", day.toString());
for (Lesson lesson : result) {
if (Objects.equals(lesson.getDay(), day)) {
dataToInsert.add(lesson);
}
}
adapter = new ScheduleListAdapter(context, result);
SwingBottomInAnimationAdapter swingBottomInAnimationAdapter = new SwingBottomInAnimationAdapter(adapter);
swingBottomInAnimationAdapter.setAbsListView(schedule_listView);
schedule_listView.setAdapter(swingBottomInAnimationAdapter);
adapter.notifyDataSetChanged();
}
}
I also have a Spinner in Toolbar with weeks. So also I want to update the fragment when I pick another week.
Please, guys. Help me. I`ve tried some solutions, but none of them helped me!
Hope for you assistance
I'm probably not an expert on this, but I just completed a project full of fragments. The 'dirty' way I passed data between them was accomplished by using a singleton class in my project. This probably isn't the best solution, though.
For instance, my project included a fragment which I updated based on options in a settings activity. The FamilyMap (familyMap) class is my singleton, and I kept a settings model containing maps of needing information within that object. The code shown here is updating that settings model based on user interaction.
public void mapTypeSelection(String selection)
{
Log.d("Map Selection", selection);
switch(selection)
{
case "Normal":
familyMap.getMapFrag().getmMap().setMapType(GoogleMap.MAP_TYPE_NORMAL);
familyMap.getSettings().setMapType(new Pair<String, Integer>("Normal", GoogleMap.MAP_TYPE_NORMAL));
break;
case "Satellite":
familyMap.getMapFrag().getmMap().setMapType(GoogleMap.MAP_TYPE_SATELLITE);
familyMap.getSettings().setMapType(new Pair<String, Integer>("Satellite", GoogleMap.MAP_TYPE_SATELLITE));
break;
case "Hybrid":
familyMap.getMapFrag().getmMap().setMapType(GoogleMap.MAP_TYPE_HYBRID);
familyMap.getSettings().setMapType(new Pair<String, Integer>("Hybrid", GoogleMap.MAP_TYPE_HYBRID));
break;
case "Terrain":
familyMap.getMapFrag().getmMap().setMapType(GoogleMap.MAP_TYPE_TERRAIN);
familyMap.getSettings().setMapType(new Pair<String, Integer>("Terrain", GoogleMap.MAP_TYPE_TERRAIN));
break;
default:
break;
}
}
//private method of your class
private int getIndex(Spinner spinner, String myString)
{
int index = 0;
for (int i=0;i<spinner.getCount();i++){
if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(myString)){
index = i;
break;
}
}
return index;
}
public Pair<String, Integer> colorLineSelection(String selection)
{
Log.d("Map Selection", selection);
switch(selection)
{
case "Red":
return new Pair<String, Integer>("Red", Color.RED);
case "Blue":
return new Pair<String, Integer>("Blue", Color.BLUE);
case "Green":
return new Pair<String, Integer>("Green", Color.GREEN);
default:
return null;
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch(parent.getId()){
case R.id.mapTypeSpinner:
mapTypeSelection((String)parent.getItemAtPosition(position));
break;
case R.id.lifeLineSpinner:
FamilyMap.getInstance().getSettings().setLifeColor(colorLineSelection((String)parent.getItemAtPosition(position)));
familyMap.getMapFrag().drawLines();
break;
case R.id.spouseLineSpinner:
FamilyMap.getInstance().getSettings().setSpouseColor(colorLineSelection((String) parent.getItemAtPosition(position)));
familyMap.getMapFrag().drawLines();
break;
case R.id.familyLineSpinner:
FamilyMap.getInstance().getSettings().setFamilyColor(colorLineSelection((String) parent.getItemAtPosition(position)));
familyMap.getMapFrag().drawLines();
break;
default:
break;
}
}
The other thing I did was I retained the instance of my fragment - it was the main portion of my app, so it made sense for my situation. That allowed me to be able to update the original fragment when an option was selected. I also set the fragment to update when a certain result was reached by using startActivityForResult().
I think a better (cleaner, more acceptable) option for sending the data to your fragment would be object serialization, but at least in my case, that proved to be more work than I could afford at the time.
Hopefully this at least helps to point you in the right direction!
So, after trying, trying and a lot of trying I figured it out!
In newInstance method, where I create new instance of Fragment I`ve added a bundle with day, according to fragments position
public ScheduleFragment newInstance(Integer day) {
ScheduleFragment fragment = new ScheduleFragment();
Bundle args = new Bundle();
args.putInt("day", day);
fragment.setArguments(args);
return fragment;
}
Then, in fragment's onCreateView I get this argument with getArguments().getInt("day"); and put it into private Integer dayglob; field, which means, that its different for every fragment.
Now, when I have 'day' variable in my fragment I can put info into list according to provided day:
private class ScheduleBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ArrayList<Lesson> result = (ArrayList<Lesson>) intent.getSerializableExtra("schedule");
ArrayList<Lesson> dataToInsert = new ArrayList<>();
for (Lesson lesson : result) {
if (Objects.equals(lesson.getDay(), dayglob)) {
dataToInsert.add(lesson);
}
}
adapter = new ScheduleListAdapter(context, dataToInsert);
SwingBottomInAnimationAdapter swingBottomInAnimationAdapter = new SwingBottomInAnimationAdapter(adapter);
swingBottomInAnimationAdapter.setAbsListView(schedule_listView);
schedule_listView.setAdapter(swingBottomInAnimationAdapter);
try {
getActivity().unregisterReceiver(mScheduleBroadcastReceiver);
} catch (IllegalArgumentException e) {
Log.i("Unregister", e.toString());
}
}
}
Every fragment got its own "onReceive" and wor on data from service for specific fragment.
Also, about the week spinner and updating the lists according to its value: I've made a static field public static Spinner week_spinner;, initialized it it onCreate method of my Activity and then, in fragment's "onCreateView" I made a request to my database like this:
requestQueue.add(connectionManager.getSchedule(this, savedUser.getGroup(), MainActivity.week_spinner.getSelectedItemPosition() + 1));
The only matter thing here is getting value by accessing spinner via static reference.
And, also, I've set Listener which says to fragments something like
Hey, guys! You are not up to date! Update yourself!
week_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mViewPager.getAdapter().notifyDataSetChanged();
}
});
And a little trick which make it possible is to change getItemPositionin FragmentPagerAdapter class (SectionsPagerAdapter in my case)
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
It`s kinda tricky, I guess, but its the only way i can figure it out
I hope, this will help someone!
This question has been answered before, but the solutions doesn't seem to work for me. I would like to know what the best way is to save an ArrayList.
I generate an ArrayList with all the installed applications on the phone. This list is shown in a ListView where the user can (de)select apps. This is all working fine. What I would like is that the Arraylist gets saved when the user presses a save button or when the activity calls onPause().
When the user returns to the list the user will see the list the way he saved/left it.
Here is my code:
onCreate
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_list);
loadApps();
loadListView();
addClickListener();
}
loadApps
private void loadApps(){
manager = getPackageManager();
apps = new ArrayList<AppDetail>();
if(apps.size()==0) {
Intent i = new Intent(Intent.ACTION_MAIN, null);
i.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> availableActivities = manager.queryIntentActivities(i, 0);
for (ResolveInfo ri : availableActivities) {
AppDetail app = new AppDetail();
app.label = ri.loadLabel(manager);
app.name = ri.activityInfo.packageName;
app.icon = ri.activityInfo.loadIcon(manager);
app.allowed = false;
apps.add(app);
}
Log.i("applist", apps.toString());
}
}
AppDetail.class
public class AppDetail {
CharSequence label;
CharSequence name;
Drawable icon;
Boolean allowed;
loadListView
private void loadListView(){
list = (ListView)findViewById(R.id.apps_list);
adapter = new ArrayAdapter<AppDetail>(this, R.layout.list_item, apps) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = getLayoutInflater().inflate(R.layout.list_item, null);
}
ImageView appIcon = (ImageView)convertView.findViewById(R.id.item_app_icon);
appIcon.setImageDrawable(apps.get(position).icon);
TextView appLabel = (TextView)convertView.findViewById(R.id.item_app_label);
appLabel.setText(apps.get(position).label);
TextView appName = (TextView)convertView.findViewById(R.id.item_app_name);
appName.setText(apps.get(position).name);
if(list.isItemChecked(position)){convertView.setBackgroundColor(getResources().getColor(R.color.green));}
if(!list.isItemChecked(position)){convertView.setBackgroundColor(getResources().getColor(R.color.white));}
return convertView;
}
};
list.setAdapter(adapter);
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
addClickListener
private void addClickListener() {
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int pos,
long id) {
checked = list.getCheckedItemPositions();
ArrayList<AppDetail> allowedApps = new ArrayList<>();
for (int i = 0; i < checked.size(); i++) {
// Item position in adapter
int position = checked.keyAt(i);
// Add sport if it is checked i.e.) == TRUE!
if (checked.valueAt(i)) {
allowedApps.add(adapter.getItem(position));
}
}
adapter.notifyDataSetChanged();
Log.i("", allowedApps.toString());
}
});
}
At this moment I'm creating two lists:
List: list of all apps
AllowedApps: list of checked (allowed) apps, to use in an other activity
If you need saving your list when activity is paused, you have several ways to do it. First you need define the private list field in your activity.
private ArrayList<AppDetail> allowedApps;
1) Make AppDetail serializable and use onSaveInstanceState
public class AppDetail implements Serializable {
CharSequence label;
CharSequence name;
Drawable icon;
Boolean allowed;
}
---------------- EDIT -----------------
I would change Drawable icon field for int icon.
In your loadApps() method change the setence app.icon = ri.activityInfo.getIconResource();
In yout loadListView method change the setence appIcon.setImageResource(apps.get(position).icon);
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("allowedApps", allowedApps);
}
Retrieve the list in onCreate method
if (savedInstanceState != null) {
allowedApps = (List<AppDetail>)savedInstanceState.getSerializable("allowedApps");
}else{
allowedApps = new ArrayList<AppDetail>();
}
2) Use onRetainCustomNonConfigurationInstance
Return the list in onRetainCustomNonConfigurationInstance
#Override
public Object onRetainCustomNonConfigurationInstance() {
return allowedApps;
}
Retrieve the list in onCreate method
Object allowedApps= getLastCustomNonConfigurationInstance();
if (allowedApps != null) {
this.allowedApps = (List<AppDetail>) allowedApps;
}else{
this.allowedApps = new ArrayList<AppDetail>();
}
I think you are looking for something like "Parcelable". It can save any ArrayList and retrieve back when you need it just like the Shared Preferences.
Please have a look here,
How to save custom ArrayList on Android screen rotate?
ArrayList is serializable. Save it as a serializable object in file on storage