In my activity, on click of a button I am opening a Dialog which has a RecyclerView in it.
final Dialog dialog = new Dialog(MyActivity.this);
dialog.setTitle("Details");
dialog.setContentView(R.layout.details_popup);
RecyclerView detailsRecyclerView = (RecyclerView) dialog.findViewById(R.id.detailsRecyclerView);
Button detailsCloseButton = (Button) dialog.findViewById(R.id.detailsCloseButton);
//feedbackResponseSubList contains n items
**DetailsAdapter detailsAdapter = new DetailsAdapter(R.layout.detail_item, feedbackResponseSubList);
detailsRecyclerView.setAdapter(detailsAdapter);**
detailsCloseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
The close button is visible but the recyclerView is not getting populated with data. Even the methods onCreateViewHolder(), onBindViewHolder() and getItemCount() of Detailsdapter are not getting called.
I have figured out the problem. After setting layout manager in recyclerview, it works fine.
LinearLayoutManager layoutManager = new LinearLayoutManager(dialog.getContext());
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
detailsRecyclerView.setLayoutManager(layoutManager);
The problem is that the Dialog is already created when you try to modify the adapter, because of that It's not getting populated with your data.
You have two options, create your own Dialog which extend Dialog class and in onCreate() put your code to populate the list or add adapter.notifyDataSetChanged() after setAdapter() to tell that your data inside the list was updated.
Use a dialog fragment instead of Dialog. An dialog fragment gives all the features of a dialog while providing the functionality of a fragment.
public class AlertDialogFragment extends DialogFragment {
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//inflate layout with recycler view
View v = inflater.inflate(R.layout.details_popup, container, false);
RecyclerView detailsRecyclerView = (RecyclerView) getActivity().findViewById(R.id.detailsRecyclerView);
DetailsAdapter detailsAdapter = new DetailsAdapter(R.layout.detail_item, feedbackResponseSubList);
detailsRecyclerView.setAdapter(detailsAdapter);
detailsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return v;
}
public Dialog onCreateDialog(Bundle SavedInstanceState) {
//The rest of the code you will get when u search for dialogfragments
Related
For some reason my recyclerView doesn't attach to the Firebase RecyclerView adapter. I'm implementing the recyclerView inside a fragment that shows in a tabbed activity. my code (relevant parts):
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = LayoutInflater.from(container.getContext())
.inflate(R.layout.fragment_fresh, container, false);
// Initialize ProgressBar and RecyclerView.
mProgressBar = (ProgressBar)rootView.findViewById(R.id.progressBar);
mSessionRecyclerView = (RecyclerView) rootView.findViewById(R.id.sessionRecyclerView);
mLinearLayoutManager = new LinearLayoutManager(getActivity());
mLinearLayoutManager.setStackFromEnd(true);
mSessionRecyclerView.setLayoutManager(mLinearLayoutManager);
//implement recyclerview
mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
mFirebaseAdapter = new FirebaseRecyclerAdapter<Session, SessionViewHolder>(
Session.class,
R.layout.item_session,
SessionViewHolder.class,
//change back to SESSIONS_CHILD
mFirebaseDatabaseReference.child("test")) {
#Override
protected void populateViewHolder(final SessionViewHolder viewHolder,
Session session, int position) {
//implementing populateViewHolder..
}
};
mSessionRecyclerView.setLayoutManager(mLinearLayoutManager);
mSessionRecyclerView.setAdapter(mFirebaseAdapter);
return inflater.inflate(R.layout.fragment_fresh, container, false);
}
}
The XML is just a recyclerView and a progressBar.
Worth mentioning that I've gone through this thread.Tried setting recycler's size to wrap_parent, move setAdapter to onCreate, and pretty much every other answer - to no avail.
EDIT: I got this working when inside an activity, but whenever I try from within a fragments I get this error. Also tried with a regular recyclerView and a custom adapter and the same thing happens.
Does the recyclerView attaches itself to an adapter differently in a fragment?
OK, I finally fixed it. The problem was actually in the tabbed activity - the getItem method inside the PlaceHolder fragment created a new instance of PlaceHolder.
Therefore, my fragments hadn't even been created.
None of the threads on the skipping layout advise checking that, hope this helps.
i got a problem here. As the title said, i want to update a listview in a fragment adding a value from an edittext of another fragment. My main activity is a navigation drawer. My fragment with the listview is the Fragment_hotels and the other fragment witch contains the edittext is the FragmentAddHotel. I want to add in the listview (with the hotels) a new hotel.
Can someone explain how to do that?
Code given below:
Fragment_hotels:
public class Fragment_hotels extends Fragment {
public static boolean flag=false;
public void Add(){
Target.add("Hotel");
Target.add("Hotel1");
Target.add("Hotel2");
}
static ArrayList<String> Target = new ArrayList<String>();
#Override
public View onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_hotels, container,false);
ListView listView = (ListView) view.findViewById(R.id.list);
if (flag==false){
this.Add();
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),R.layout.mytextview,R.id.tv, Target);
adapter.setNotifyOnChange(true);
// Assign adapter to ListView
listView.setAdapter(adapter);
return view;
}
}
And FragmentAddHotel:
public class FragmentAddHotel extends Fragment {
public View onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment_add_hotel, container, false);
return rootView;
}
}
I got an edittext and a button on my FragmentAddHotel layout.
How can i get the value from edittext and add it on the listview?
Sorry if a similar question has already been answered but i am junior programmer.
Tnx in advance :)
To update view in class from another one you can use EventBus library here is the link
Just register you first class by adding:
EventBus.getDefault().register(this); //in your listener class that contains the listview at onCreate method.
Also implement your receiver method:
public void onEventMainThread(String hotelName) {
// Add the hotelName in your Target array list and then notify your adapter by adapter.notifyDataSetChanged();
}
To send data from your fragment just use :
EventBus.getDefault().post("edittextvalue");
Also don't forget to call :
EventBus.getDefault().unregister(this); // In your listener class onDestroy() method.
In YourActivity:
Fragment_hotels frag_hotels;
void addItem(String item){
frag_hotels.addItemToList(item);
}
Fragment_hotels:
List<String> hotelList;
ArrayAdapter<String> adapter;
void addItemToList(String item){
hotelList.add(item);
adapter.notifyDataSetChanged();
}
In FragmentAddHotel:
// you should call whenever adding is need in fragment
((YourActivity)getActivity()).addItem("Your Item");
Through YourActivity, you can communicate each fragment.
I dont know what path to take, I have a MainActivity class which host my ViewPagerTabStrip and each tabs are fragments, one tab consist of ListView and a button. When I click that button I want to either inflate a UI where the user fills in editfields or dialogFragment similiar process. Working with fragments what is best way to implement this? and How can I? I have set a onClickListener on the button and is working.
I have a method in my DBHelper that puts the users input into an SQLite database.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_notes, container, false);
add = (Button) view.findViewById(R.id.addbtn);
add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(getActivity(), "onClick works", Toast.LENGTH_SHORT).show();
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
LayoutInflater inflater= getActivity().getLayoutInflater();
//this is what I did to added the layout to the alert dialog
View layout= inflarter.inflate(R.layout.alert_dialog,null);
alert.setView(layout);
final EditText titleInput=(EditText)layout.findViewById(R.id.dialog_title);
final EditText bodyInput=(EditText)layout.findViewById(R.id.dialog_body);
}
});
return view;
}
What do I call in the Fragment
Simplest way would be to use an AlertDialog with a custom layout, which has has some EditTexts. When the OK button in the dialog is clicked, get the values from the EditTexts, and put them in your database.
I am creating a dialog and setting setContentView of a layout. And I am programmatically adding buttons, images to layout in dialog setContentView . Now how I can assign dialog box view to another view.
That is a layout is assigned to a a view like below
View getview=R.layout.tamil_alphabet_speak_word;
Similarly how can I assign the dialog box view to another view. Since I am adding all elements to the view "TamilAlphabets" programmatically the child are null it returns for the below code.
Alphbetdialog=new Dialog(TamilAlphabets.this);
Alphbetdialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
Alphbetdialog.setContentView(R.layout.tamil_alphabetsdialog);
(adding elements to the layout "TamilAlphabets" code
..............
)
LayoutInflater inflator=(LayoutInflater)TamilAlphabets.this.getSystemService
(TamilAlphabets.this.LAYOUT_INFLATER_SERVICE);
View row=inflator.inflate(tamil_alphabetsdialog, Parent,false);
LinearLayout l1=(LinearLayout)row.findViewById(R.id.alphabetlayout1);
ViewGroup vg=(ViewGroup)l1;
vg.getChildCount();
So I need to assign the dialog box view to another view how do I do that.
I need something like this
View getview=<I need dialog box view>
You should avoid using Dialog class directly and instead use Dialog subclass's or DialogFragment
https://developer.android.com/guide/topics/ui/dialogs.html:
The Dialog class is the base class for dialogs, but you should avoid instantiating Dialog directly. Instead, use one of the following subclasses:
AlertDialog
A dialog that can show a title, up to three buttons, a list of selectable items, or a custom layout.
DatePickerDialog or TimePickerDialog
A dialog with a pre-defined UI that allows the user to select a date or time.
In any case im guessing that what you want is a custom dialog and what is recomendaded is using the DialogFragment class in that case here is an example
Dialog fragment layout
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent">
Dialog class
public class DialogExampleFragment extends DialogFragment {
private static final String ARG_PARAM = "extra:PARAM";
private String mText;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arguments = getArguments();
mText = arguments.getString(ARG_PARAM);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setTitle("title");
return dialog;
}
public static DialogExampleFragment newInstance(String message) {
Bundle args = new Bundle();
args.putSerializable(ARG_PARAM, message);
DialogExampleFragment fragment = new DialogExampleFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_dialog_example, container, false);
TextView t = (TextView) root.findViewById(R.id.textView1);
t.setText(mText);
return root;
}
}
To show as a dialog
DialogExampleFragment.newInstance("Message")
.show(getFragmentManager(), "dialog");
Note since a DialogFragment is a fragment it has de advantage of being able to be shown as a Dialog or as a regular fragment you can get all the information on the link i posted above
I'm trying to create a DialogFragment that shows a dialog with a custom ListView inside.
public class MultiSelectDialogCustom extends DialogFragment {
ListView mLocationList;
private ArrayList<String> mOfficeListItems = new ArrayList<String>();
public static MultiSelectDialogCustom newInstance(int title) {
MultiSelectDialogCustom dialog = new MultiSelectDialogCustom();
Bundle args = new Bundle();
args.putInt("title", title);
dialog.setArguments(args);
return dialog;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Collections.addAll(mOfficeListItems, getResources().getStringArray(R.array.offices));
View v = inflater.inflate(R.layout.fragment_choice_list, container,
true);
mLocationList = (ListView)v.findViewById(R.id.location_criteria_list);
final FunctionListArrayAdapter adapter = new FunctionListArrayAdapter(
this, android.R.layout.simple_list_item_1, mOfficeListItems);
mLocationList.setAdapter(adapter);
getDialog().setTitle(getArguments().getInt("title"));
return v;
}
}
When calling it from a fragment :
MultiSelectDialogCustom dialogFrag = MultiSelectDialogCustom_.newInstance(R.string.dialog_title);
dialogFrag.show(getActivity().getSupportFragmentManager(), null);
It only shows a blank dialog with the title... why my isn't my list displayed?
Instead of using onCreateView you should be overriding onCreateDialog and inside of it, it'll look something like:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Collections.addAll(mOfficeListItems, getResources().getStringArray(R.array.offices));
View v = getActivity().getLayoutInflater().inflate(R.layout.fragment_choice_list, null);
mLocationList = (ListView)v.findViewById(R.id.location_criteria_list);
final FunctionListArrayAdapter adapter = new FunctionListArrayAdapter(
this, android.R.layout.simple_list_item_1, mOfficeListItems);
mLocationList.setAdapter(adapter);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getArguments().getInt("title")).setView(v);
return builder.create();
}
This quote from the DialogFragment documentation page describes what you're trying to do:
Implementations should override this class and implement onCreateView(LayoutInflater, ViewGroup, Bundle) to supply the content of the dialog. Alternatively, they can override onCreateDialog(Bundle) to create an entirely custom dialog, such as an AlertDialog, with its own content.
In your case, it seems like onCreateDialog is the way to go since you want to do a custom inner view.
May be you are missing something very small but important. Are you missing notifyDataSetChanged() in your adapter?
"Once you have added the new item to the adapter you have to call notifyDataSetChanged() so that the listview refreshes itself with the new set of data found in the adapter."
what I forgot was:
view.setAdapter(adapter);
after I added that the code worked