So I'm trying to load different contents in a ListView when I press on specific buttons but it only loads the first that I tried to load (and only after I have pressed it twice). I can't find what I've done wrong.
Here's the code that creates the view in witch I show the content:
public class ContentQuery extends Fragment {
private List<String> contents_list = new ArrayList<String>();
public static final String TAG = contentQuery.class.getSimpleName();
private String uri = "";
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View lv = inflater.inflate(R.layout.contents_list, container, false);
super.onActivityCreated(savedInstanceState);
getContent(); // Sets contents_list
((ListView) lv).setAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, contents_list));
return lv;
}
}
I think it might be because I should in some way destroy it but I'm pretty new to android dev.
tag = ContentQuery.TAG;
ContentQuery contentqueryfragment = null;
final Fragment foundFragment = fm.findFragmentByTag(tag);
if (foundFragment != null && uri != old_uri) {
fragment = foundFragment;
contentqueryfragment = (ContentQuery) fragment;
old_uri = uri;
} else {
contentqueryfragment = new ContentQuery();
contentqueryfragment.setUri(uri.toString());
fragment = contentqueryfragment;
}
And after:
if (fragment.isAdded())
{
tr.show(fragment);
} else
{
tr.remove(fragment);
tr.add(R.id.content, fragment, tag);
tr.show(fragment);
}
tr.commit();
currentUri = uri;
currentContentFragmentTag = tag;
If you need to update the content within the List a good approach would be to separate the List, ListAdapter and ListView. When data needs to be updated, update the contents of the list and notify the Adapter that the list contents changed.
eg.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, contents_list);
((ListView) lv).setAdapter(adapter);
...
button.onClickListener(...) {
contents_list.clear();
... populate list with new data ...
adapter.notifyDataSetChanged();
}
Related
I am new to android please help me to play audio on list item click in fragment. I am using this code but on item click my app gets crash showing error.
I have tried the below code but my app crashes on click on item:
public class FragmentOne extends Fragment {
static MediaPlayer mediaPlaye;
int audioIndex;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_fragment_one, container, false);
ListView audioView = view.findViewById(R.id.listview1);
final ArrayList<String> audioList = new ArrayList<>();
String[] proj = {MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME};
final Cursor audioCursor = getActivity().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, proj, null, null, null);
if (audioCursor != null) {
if (audioCursor.moveToFirst()) {
do {
audioIndex = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
audioList.add(audioCursor.getString(audioIndex));
} while (audioCursor.moveToNext());
}
}
audioCursor.close();
final ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(),R.layout.tectcolor, audioList);
audioView.setAdapter(adapter);
audioView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Uri u = Uri.parse(audioList.get(i).toString());
mediaPlaye = MediaPlayer.create(getContext(), u);
mediaPlaye.start();
}
});
return view;
}
}
I am expecting to play audio on item click in fragment.
u must setOnclick in your Custom Adapter.
when u set onClick on your List, Android check all of your view of List and it will cause a crash.
create an adapter and override onClick in there.
have good coding...
public class AlarmsFragment extends Fragment {
FloatingActionButton floatingActionButton;
RecyclerView recyclerView;
TextView checkText;
ArrayList<AlarmObjects> alarmObjects;
public AlarmsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_alarms, container, false);
floatingActionButton = v.findViewById(R.id.fab_button);
recyclerView = v.findViewById(R.id.rv_alarms);
alarmObjects = new ArrayList<>();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
RecyclerView.LayoutManager rvLayoutManager = linearLayoutManager;
recyclerView.setLayoutManager(rvLayoutManager);
AlarmAdapter alarmAdapter = new AlarmAdapter(getContext(),alarmObjects);
recyclerView.setAdapter(alarmAdapter);
Bundle arguments = getArguments();
if (arguments != null){
String newTime = getArguments().getString("newTimm");
String newNotes = getArguments().getString("newNott");
checkText.setText(newTime + newNotes);
alarmObjects.add(new AlarmObjects(newNotes,newTime));
}
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((MainActivity)getActivity()).showPopupmeth();
}
});
return v;
}
}
it keeps updating same object it created but doesnt create new one can you help i am new to this.
public void setFragment(Fragment fragment, int id) {
changeTitle(id);
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_frame, fragment);
fragmentTransaction.commit();
}
using this method i come back to my alarmsFragment. When i come back to it from dialog fragment it creates new ArrayList every time as i understood. How can i make it show existing objects and add new ones using getArguments
Your is only part in and not clear enough, So I am assuming that you want create Immutable ArrayList,You can implement it as follows by using unmodifiableList method of Collections framework Java 8
i.e Collections unmodifiableList(list);
Example :
List<String> list = new ArrayList<String>(Arrays.asList("one", "two", "three"));
List<String> unmodifiableList = Collections.unmodifiableList(list);
unmodifiableList.add("four");
This is only a part of the code. I assume the code above is being called for every new arguments. If so, then the following is what is happening:
On the first line you are doing new ArrayList() which always creates a new (and empty) array list.
On the last line you are adding a new AlarmObjects to the list.
So, when you try to retrieve the element from the list you get the most recently added element. This is why you are thinking it is modifying the existing element.
In reality, you are adding a new element. But you are also recreating the list every time. So you are not seeing the previous element
Instead of creating a new arraylist every time, create one in the parent method and pass the reference to this method.
public void parentMethod(){
List<AlarmObjects> alarmObjects = new ArrayList<>();
childMethod(alarmObjects);
}
public void childMethod(List<AlarmObjects> alarmObjects){
//all of your code except the new ArrayList<>() goes here
}
Sorry but I cannot get what you want to do.
You initialize an ArrayList here:
alarmObjects = new ArrayList<>();
And put the first object into the array here:
alarmObjects.add(new AlarmObjects(newNotes,newTime)); }
What behaviour do you expect?
EDIT:
try this:
FloatingActionButton floatingActionButton;
RecyclerView recyclerView;
TextView checkText;
ArrayList<AlarmObjects> alarmObjects = new ArrayList<>();
public AlarmsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_alarms, container, false);
floatingActionButton = v.findViewById(R.id.fab_button);
recyclerView = v.findViewById(R.id.rv_alarms);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
RecyclerView.LayoutManager rvLayoutManager = linearLayoutManager;
recyclerView.setLayoutManager(rvLayoutManager);
AlarmAdapter alarmAdapter = new AlarmAdapter(getContext(),alarmObjects);
recyclerView.setAdapter(alarmAdapter);
Bundle arguments = getArguments();
if (arguments != null){
String newTime = getArguments().getString("newTimm");
String newNotes = getArguments().getString("newNott");
checkText.setText(newTime + newNotes);
alarmObjects.add(new AlarmObjects(newNotes,newTime));
}
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((MainActivity)getActivity()).showPopupmeth();
}
});
return v;
enter code here
}
}
I have a listview that shows up when a fragment is opened being updated by a saved list. Initially that list is empty so it spits out an error java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0. So i want to show show something like a text saying something like empty so that when there is something in the list it will display. I have tried using the getEmptyView but to no avail. Can i please get some help on how to accomplish this thank you.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View customView = inflater.inflate(R.layout.fragment_reading_monday, container, false);
addNewButton = (Button) customView.findViewById(R.id.btnAddNewReadingMonday);
relativeLayoutMonday = (RelativeLayout) customView.findViewById(R.id.frameLayoutMonday);
listViewMonday = (ListView)customView.findViewById(R.id.listViewMonday);
listContainerMonday = (RelativeLayout)customView.findViewById(R.id.listContainerMonday);
tinyDB = new TinyDB(getContext());
addNewSubject = (Button)customView.findViewById(R.id.btnAddNewSubjectMonday);
dataModels = new ArrayList<>();
arrayListSubjectsRead = new ArrayList<>();
timeOne = new ArrayList<>();
timeTwo = new ArrayList<>();
adapter = new CustomListAdapterReading(getContext(), dataModels);
TextView empty = (TextView) customView.findViewById(R.id.emptyTextView);
listViewMonday.setEmptyView(empty);
arrayListSubjectsRead = tinyDB.getListString("ArrayForSubjects");
timeOne = tinyDB.getListString("ArrayForTimeOne");
timeTwo = tinyDB.getListString("ArrayForTimeTwo");
dataModels.add(new DataModelReading(arrayListSubjectsRead, timeOne, timeTwo));
adapter = new CustomListAdapterReading(getContext(), dataModels);
listViewMonday.setAdapter(adapter);
adapter.notifyDataSetChanged();
System.out.println(" subjects: "+arrayListSubjectsRead);
System.out.println("timeone: "+ timeOne);
System.out.println("timetwo: "+timeTwo);
addNewButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
relativeLayoutMonday.removeView(noEventTextView);
Intent intent = new Intent(getActivity(),ReadMain.class);
startActivity(intent);
}
});
addNewSubject.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
return customView;
}
I want you to check this post setEmptyView on ListView not showing its view in a android app, it should solve your empty view issue.
And if you want to prevent the app from throwing an IndexOutOfBoundsException, you can simply check the size of your dataModels array before setting up your adapter.
if (dataModels.size() > 0)
{
//Setup our adapter here
}
Hope this helps :)
Something like this ?
ImageListAdapter imageListAdapter= new ImageListAdapter();
listviewObject.setAdapter(imageListAdapter);
if (imageListAdapter!= null)
if (imageListAdapter.getCount() > 0){
// implement your work
}else {
// do whatever you want on empty list adapter
}
I am using this way in my application
ListView listView = (ListView)findViewById(android.R.id.listView);
TextView noData = (TextView)findViewById(android.R.id.noData);
listView.setEmptyView(noData);
Listview will automatically set no data text when adapter is empty.
I have a fragment which doesn't contain anything at the application start, but after the data is loaded it should show the loaded data. I do all my data loading in MainActivity in function onDataLoaded which implements DataLoadedListener. After the data is loaded the function sends the data (ArrayList) as a parameter through the function call (initializeAdapter()). Then, the function initializeAdapter() gets it and initialize custom made adapter (adapter is a global object, initialized in initializeAdapter() and used in onCreateView()).
I guess that I should refresh fragment view after the data is loaded and the adapter is initialized, but I don't know how to do it. I tried in a lot of ways but didn't make it.
onDataLoaded function in MainActivity which calls initializeAdapter()
#Override
public void onDataLoaded(List<Grad> gradovi, List<Ponuda> ponude) {
Spinner spinnerGradovi = (Spinner) findViewById(R.id.gradovi_spinner);
ArrayAdapter<String> adapterGradovi;
List<String> listaGradova = new ArrayList<>();
ArrayList<Ponuda> ponudaArrayList = new ArrayList<Ponuda>();
ponudaLista = ponude;
gradLista = gradovi;
for(Grad grad : gradovi ){
listaGradova.add(grad.getNaziv());
}
for(Ponuda ponuda : ponude){
ponudaArrayList.add(ponuda);
}
adapterGradovi = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, listaGradova);
spinnerGradovi.setAdapter(adapterGradovi);
Fragment fragmentGet = svePonudeFragment;
((SvePonudeFragment)fragmentGet).initializeAdapter(ponudaArrayList);
}
and this is a Fragment
public class SvePonudeFragment extends Fragment {
private RecyclerView rv;
RVAdapter adapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.sve_ponude_fragment, container, false);
rv = (RecyclerView) rootView.findViewById(R.id.rv);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
rv.setAdapter(adapter);
return rootView;
}
public void initializeAdapter(List<Ponuda> preuzetePonude){
adapter = new RVAdapter(preuzetePonude);
//this isn't working
/*FragmentManager manager = getActivity().getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft = manager.beginTransaction();
ft.detach(this).attach(this).commit();*/
//this is not working, neither
Fragment frg = getFragmentManager().findFragmentByTag("sve_ponude_fragment_tag");
final android.support.v4.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(frg);
ft.attach(frg);
ft.commit();
}
}
I am also interested in how to make an empty adapter which loads if data is not loaded yet? And when the data is loaded to fill out another adapter and use it.
Initialize adapter before you set. If you interested to change you approach I can give suggestions: Create a constructor for you fragment which you can pass the ArrayList. OnCreate or OnCreateView you can initialize the adapter and pass the list into. After setting adapter notifyDataChanges and to check if there is data please use some Logs when you pass the data and before you pass the data. Do not directly blame the adapter or fragment control your data. Besides I suggest you to study more using fragments + RecyclerView. I am posting one example that you can look at but the data load in the fragment.
public class CategoryFragment extends Fragment {
//Class Tag
private static final String TAG = CategoryFragment.class.getSimpleName();
//Fragments base context
private Context mContext;
//RecyclerView widget
private RecyclerView mRecyclerView;
//RecyclerView's Layout Manager
private RecyclerView.LayoutManager mLayourManager;
//RecyclerView's Adapter
private CategoryFragmentAdapter mCategoryFragmentAdapter;
//Category Data List
private ArrayList<Category> mCategoryList;
//Interface object
onCategoryItemClick mCallBackCategory;
#Override
public void onAttach(Context context) {
super.onAttach(context);
//Instantiate base context
mContext = context;
//Instantiate interface
mCallBackCategory = (onCategoryItemClick)getActivity();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Instantiate Category List
mCategoryList = new ArrayList<Category>();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
//Custom fragment view instantiating
View view_fragment_category = inflater.inflate(R.layout.fragment_items, container, false);
//Instantiating Fragment's recycler view
mRecyclerView = (RecyclerView) view_fragment_category.findViewById(R.id.recycle_categories);
//Instantiate RecycleView's Layout Manager: LinearLayoutManager is one of the default
mLayourManager = new LinearLayoutManager(mContext);
//Setting layout manager for recycler view
mRecyclerView.setLayoutManager(mLayourManager);
//Retrieve data from server, populate the category data list and set the RecyclerView's adapter
getCategories();
//Instantiate the adapter and push the data
mCategoryFragmentAdapter = new CategoryFragmentAdapter(mContext, mCategoryList);
//RecyclerView item click listener
mCategoryFragmentAdapter.SetOnItemClickListener(new CategoryFragmentAdapter.OnItemClickListener() {
#Override
public void onItemClick(View v , int position) {
//Test display
//Toast.makeText(mContext, mCategoryList.get(position).getId(),Toast.LENGTH_LONG).show();
//Push to Activity method with clicked item ID
mCallBackCategory.proceedToProducts(mCategoryList.get(position).getId());
}
});
return view_fragment_category;
}
I try to fill a listView with the following code:
private void getPhoneComments(View rootView) {
String phoneNumber = ((EditText) rootView.findViewById(R.id.phone_editText)).getText().toString();
Phone phone = phoneDal.getItem(phoneNumber);
if (phone != null) {
List<String> comments = commentDal.getAllItems(phone.id);
ListView lv = ((ListView) rootView.findViewById(R.id.comments_list));
// This is the array adapter, it takes the context of the activity as a
// first parameter, the type of list view as a second parameter and your
// array as a third parameter.
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(
getActivity(),
android.R.layout.simple_list_item_1,
comments);
lv.setAdapter(arrayAdapter);
}
}
but the list still isn't displayed to the screen.
1) When do I need to add invalidate data
or what else I need to change in order to code to work?
2) how can i disply an option popup when there was a long push on each list item?
Edit:
phone != null
comments != empty
lv is set OK:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_item_detail, container, false);
setCommentsVisibility(rootView, false);
lv = ((ListView) rootView.findViewById(R.id.comments_list));