The goal is to create a dialog that shows a list of files.
The problem is that once I remove the title (by any means including window feature, setting style, using styles.xml...) the dialog window converts to wrap_content constraint.
No property I set in layout influences this.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/dialog_files_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="8dp"
android:text="#string/dialog_files_title"
android:textColor="#color/colorTextActive"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Title" />
<android.support.v7.widget.RecyclerView
android:id="#+id/dialog_files_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />
</LinearLayout>
my java code
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
#SuppressLint("InflateParams") View view = inflater.inflate(R.layout.dialog_files, null);
paths = new ArrayList<>();
recursiveScan(Environment.getExternalStorageDirectory());
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dialog_files_recycler_view);
GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
AdapterFiles adapter = new AdapterFiles(getActivity(), paths);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
return view;
}
The result is this
The issue seems to be when using LinearLayout as a root layout. I switched to RelativeLayout everything fit into place. Maybe this is a bug when using LinearLayout as a root layout in dialogs and removing title?
Dialog dialog = super.onCreateDialog(savedInstanceState);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
Window window = dialog.getWindow();
if (window != null) {
window.requestFeature(Window.FEATURE_NO_TITLE);
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
}
return dialog;
Try this out.
Related
My issue:
In my xml file, I define android:visibility="gone" in the linear layout labelled as assess_layout_list. Then, in the onClick() of course_adapter_layout, the whole view, I set the visibility back to View.VISIBLE, which does not work, even though the Log call just before it works, the LinearLayout object called assess_list_layout is not null, and it does work when I define the visibility="invisible" in the xml file. I want it to be gone at first though, and visible after clicking as this fits the design of the app.
Here is my course_adapter_view.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/course_adapter_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="left"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="20dp"
android:padding="15dp"
android:elevation="2dp"
android:background="#drawable/course_header_background">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:src="#drawable/course_color_circle"/>
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.25"/>
<TextView
android:id="#+id/course_adapter_course_code"
android:text="TextView1"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_weight="0.5"/>
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.25"/>
<TextView
android:id="#+id/course_adapter_course_title"
android:text="TextView2"
android:layout_width="wrap_content"
android:layout_height="20dp"/>
</LinearLayout>
<LinearLayout
android:id="#+id/assess_list_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginRight="40dp"
android:layout_marginLeft="40dp"
android:background="#drawable/course_body_background"
android:padding="20dp"
android:visibility="gone"
>
<ListView
android:id="#+id/course_adapter_assess_list"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_marginBottom="10dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="More" />
<Space
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="New"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Here is my CourseListAdapter.java file that I use to create each view for each course in the list of courses, minus the usual stuff:
package com.example.schoolplanner2.adapters;
public class CourseListAdapter extends ArrayAdapter<Course> {
private static final String TAG = "CourseListAdapter";
private Context context;
int mResource;
public CourseListAdapter(#NonNull Context context, int resource, #NonNull ArrayList<Course> objects) {
super(context, resource, objects);
this.context = context;
mResource = resource;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
// get info
String course_code = getItem(position).getCourseCode();
Double course_grade = getItem(position).getCurrentGrade();
// make inflater and inflate the layout
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(mResource, parent, false);
TextView tv_course_code = v.findViewById(R.id.course_adapter_course_code);
TextView tv_course_title = v.findViewById(R.id.course_adapter_course_title);
tv_course_code.setText(course_code);
tv_course_title.setText(String.valueOf(course_grade));
// add on click to each list view element
LinearLayout layout = v.findViewById(R.id.course_adapter_layout);
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i(TAG, "List view element has been clicked " + course_code);
// expand the view to include a new fragment
LinearLayout assess_list_layout = view.findViewById(R.id.assess_list_layout);
assess_list_layout.setVisibility(View.VISIBLE);
// get the list view and add each course to the course view
ListView assessment_list_view = (ListView) view.findViewById(R.id.course_adapter_assess_list);
AssessmentListAdapter assessAdapter = new AssessmentListAdapter(getContext(), R.layout.assessment_adapter_view, getItem(position).getAssessmentList(), getItem(position));
assessment_list_view.setAdapter(assessAdapter);
}
});
return v;
}
}
Please let me know if there is any more information you need. Will also take suggestions on other ways of accomplishing the same thing. Thanks for your help.
~Seth.
Edit: when the assess_list_layout.setVisibility(View.VISIBLE) is outside of the onClick it does work.
Further Edit: Things I have tried so far to no avail:
moving the location of where I define the LinearLayout componenent
calling invalidate() on parent view
using runOnUiThread()
changing view to v in the line where I attempt to findViewById for assess_list_layout, they are the same thing so it does not help.
calling requestLayout() on assess_list_layout
Update: I have now managed to get the assess_list_layout section to appear when the course_adapter_layout is clicked on. The only problem now is that the view does not take up anymore space on the screen, it just turns into a scrollable view that can be scrolled up and down on to see the whole view.
Also, when I scroll to fast, it resets the view back to the way it was on bootup.
1.View Visibility not working
The Visibility is not working because the view is not rendered initially. Remove the visibility gone in the xml and handle the visibility fully in the adapter class. In the 'assess_list_layout' linerlayout height can be hardcode because inside this layout the listview height is already hardcoded. You can hardcode to 300 and check. This way will help the view to get the initial rendering.
2. Scroll issue
While scrolling the already visible 'assess_list_layout' view might be not visible. This is because we need to handle the visibility, this handling is similar to checkbox selection handling in listview. Hope the Course class is model class, in that add a another property named isSelected as boolean and set the default value to false. Please refer below the course class,
Course Class
public class Course {
private boolean isSelected = false;
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
}
please refer the below code changes in the adapter class.
public class CourseListAdapter extends ArrayAdapter<Course> {
private static final String TAG = "CourseListAdapter";
private Context context;
int mResource;
public CourseListAdapter(#NonNull Context context, int resource, #NonNull ArrayList<Course> objects) {
super(context, resource, objects);
this.context = context;
mResource = resource;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
// get info
String course_code = getItem(position).getCourseCode();
Double course_grade = getItem(position).getCurrentGrade();
// make inflater and inflate the layout
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(mResource, parent, false);
TextView tv_course_code = v.findViewById(R.id.course_adapter_course_code);
TextView tv_course_title = v.findViewById(R.id.course_adapter_course_title);
//My Change
// expand the view to include a new fragment
LinearLayout assess_list_layout = view.findViewById(R.id.assess_list_layout);
// get the list view and add each course to the course view
ListView assessment_list_view = (ListView) view.findViewById(R.id.course_adapter_assess_list);
assess_list_layout.setVisibility(View.GONE);
if (getItem().get(position).isSelected()) {
assess_list_layout.setVisibility(View.Visible);
AssessmentListAdapter assessAdapter = new AssessmentListAdapter(getContext(), R.layout.assessment_adapter_view, getItem(position).getAssessmentList(), getItem(position));
assessment_list_view.setAdapter(assessAdapter);
}
//My Change
tv_course_code.setText(course_code);
tv_course_title.setText(String.valueOf(course_grade));
// add on click to each list view element
LinearLayout layout = v.findViewById(R.id.course_adapter_layout);
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i(TAG, "List view element has been clicked " + course_code);
//My Change
getItem().get(position).setSelected(true);
//My Change
assess_list_layout.setVisibility(View.VISIBLE);
AssessmentListAdapter assessAdapter = new AssessmentListAdapter(getContext(), R.layout.assessment_adapter_view, getItem(position).getAssessmentList(), getItem(position));
assessment_list_view.setAdapter(assessAdapter);
}
});
return v;
}
}
I have commented as My Change to find the difference in the code.
issue 1
// make inflater and inflate the layout
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(mResource, parent, false);
you don't reuse view,which leads to inflate a new view every time when called getView();As inflate() method is IO sensitive,it slow down the smoothness of scrolling ,trigger jank。
try this
// make inflater and inflate the layout
View v = null;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
v= inflater.inflate(mResource, parent, false);
} else {
v = convertView;
}
issue 2
when scorll listview ,you need reset itemview state,add a "expand" property to your Course bean ,when click item set expand = true;and then add flowing code above layout.setOnClickListener
v.findViewById(R.id.assess_list_layout).setVisibility( item.expand ? View.VISIBLE:View.GONE);
ListView assessment_list_view = (ListView) v.findViewById(R.id.course_adapter_assess_list);
if (item.expand) {
AssessmentListAdapter assessAdapter = new AssessmentListAdapter(getContext(), R.layout.assessment_adapter_view,
item.getAssessmentList(), item);
assessment_list_view.setAdapter(assessAdapter);
}
issue 3
set setOnClickListener in getView() method , will create a new Clicker instance every time getView() called. use listView.setOnItemClickListener() instead
tips:
after all,you should use RecyclerView instead of ListView,which is a powerful UI widget
Im trying to dynamicaly add buttons to a fragment, but they do not show.
This is the listCharacter.java:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_list_character, container, false);
context = view.getContext();
for (int i = 1; i <= 20; i++) {
LinearLayout layout = new LinearLayout(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
Button firstBtn = new Button(this.context);
firstBtn.setId(i);
final int id_ = firstBtn.getId();
/**
* The text is not updated(?)
*/
firstBtn.setText("button " + id_);
/**
* it does not add 20 button, might be on top of each other
*/
layout.addView(firstBtn, params);
firstBtn = view.findViewById(R.id.characterNameBtn);
firstBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Toast.makeText(view.getContext(),
"Button clicked index = " + id_, Toast.LENGTH_SHORT)
.show();
Navigation.findNavController(view).navigate(R.id.action_listCharacter_to_loadCharacter);
}
});
}
return view;
}
And this is the fragment_list_character.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
tools:context=".listCharacter"
android:orientation="vertical">
<LinearLayout
android:id="#+id/list_character_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp">
<Button
android:id="#+id/characterNameBtn"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#66000000"
android:fontFamily="#font/main"
android:gravity="center"
android:padding="5dp"
android:text=""
android:textColor="#fff"
android:textSize="40sp"
/>
</LinearLayout>
</LinearLayout>
I dont get any error messages atm, but i cant see the buttons when i run the program.
The on click works and it says it has id 20.
You're adding the buttons to a LinearLayout that you are recreating each time through your loop.
for (int i = 1; i <= 20; i++) {
LinearLayout layout = new LinearLayout(context);
...
layout.addView(firstBtn, params)
....
}
layout is never added to the view that is returned. You will need to add the buttons to the view or to a child of the view that you return to see them on the screen. I think that there are a few other issues, but this would be the first one to address.
First, I created activity with RecyclerView, it works fine. My original code:
activity_agreements.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:paddingTop="8dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toTopOf="#+id/editText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:ems="10"
android:gravity="left"
android:inputType="none|text|textPersonName"
android:text="* required fields"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="#+id/btnGetSelected"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="#+id/btnGetSelected"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginBottom="4dp"
android:text="I agree"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</android.support.constraint.ConstraintLayout>
Agreements list passed to ActivityAgreements and adapter setup:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_agreements);
btnGetSelected = findViewById(R.id.btnGetSelected);
list = findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setHasFixedSize(true);
agreements = getIntent().getParcelableArrayListExtra("agreements");
AgreementsAdapter adapter = new AgreementsAdapter(this.agreements);
list.setAdapter(adapter);
My adapter code:
public class AgreementsAdapter extends RecyclerView.Adapter<AgreementsAdapter.ViewHolder>
{
ArrayList<Agreement> agreements;
public AgreementsAdapter(List<Agreement> agreements)
{
this.agreements = new ArrayList<>(agreements);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.agreement_list_item, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position)
{
holder.bindData(agreements.get(position));
holder.checkbox.setOnCheckedChangeListener(null);
holder.checkbox.setChecked(agreements.get(position).getAccepted());
//holder.checkbox.setFloorUnCheckedColor(agreements.get(position).getRequired()? Color.rgb(255,0,0):Color.rgb(0,255,0) );
holder.checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> agreements.get(holder.getAdapterPosition()).setAccepted(isChecked));
}
#Override
public int getItemCount()
{
return agreements.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder
{
private TextView textAgreementName;
private AppCompatCheckBox checkbox;
public ViewHolder(View v)
{
super(v);
//textAgreementName = v.findViewById(R.id.text_agreement_name);
checkbox = v.findViewById(R.id.checkbox_agreement_accepted);
}
public void bindData(Agreement agreement)
{
//checkbox.setFloorUnCheckedColor(agreement.getRequired()? Color.rgb(255,0,0):Color.rgb(0,0,255) );
/*if(agreement.getRequired())
{
textAgreementName.setTypeface(null, Typeface.BOLD);
textAgreementName.setText(agreement.getName() + " *");
}
else
textAgreementName.setText(agreement.getName());*/
if(agreement.getRequired())
{
checkbox.setText(agreement.getName() + " *");
checkbox.setTypeface(null, Typeface.BOLD);
}
else
{
checkbox.setText(agreement.getName());
}
}
}
}
All is fine, activity with list shows itself without any problems. Now, I want to use AlertDialog, not activity to display agreements list. I'm trying to create AlertDialog this way (in main activity):
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.activity_agreements, null);
alertDialog.setView(convertView);
RecyclerView list = convertView.findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setHasFixedSize(true);
AgreementsAdapter adapter = new AgreementsAdapter(agreements);
list.setAdapter(adapter);
alertDialog.show();
agreements variable contains agreements list (the same as previously passed to AgrrementsActivity). But it does not work - dialog is shown with custom layout, but list is always empty.
Can anybody point me what am I missing?
New code with fixed size and other suggestions:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.activity_agreements, null);
RecyclerView list = convertView.findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setHasFixedSize(true);
AgreementsAdapter adapter = new AgreementsAdapter(agreements);
list.setAdapter(adapter);
alertDialog.setView(convertView);
AlertDialog dialog = alertDialog.create();
dialog.getWindow().setLayout(600, 400);
dialog.show();
adapter.notifyDataSetChanged();
Your RecyclerView is probably showing the list, but it has a height of 0 so it looks empty.
Dialog size is kind of tricky, check this answer and try to give it a fixed height (maybe a percent of your screen height).
I know it is very late to answer this question but I have also faced the same issue. So for the people who is still facing this issue can use below technique.
If you are using Recycler View with constraint layout and have set the layout_height="0" in alert dialog then u will not be able to see the recycler View list. to resolve this issue set this
app:layout_constraintHeight_default="wrap"
in recyclerview
after hours looking for the best way to use RecyclerView and AlertDialog and ConstraintLayout, solution:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/abc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintHeight_default="wrap"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/abc" />
<ProgressBar
android:id="#+id/progressBarFavorito"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/abc" />
</androidx.constraintlayout.widget.ConstraintLayout>
for Using recyclerview in alertdialogue,u should be a bit tricky.As u use match parent,so width of recyclerview is 0 because recyclerviews dimension is set before alertdialogue is created.So you do such:
1)use runnable and set your adapter (or other activities we do with recyclerview) 1 sec delaying
or,
2)when you initialize recyclerview,then just set it's layoutparams programmactically. This solved my issue.(don't use this code blindly,i just copied it from my codes,and it may not be suitable for your one.rather just get idea about the issue.)
member_list.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
I want to customize my title in my DialogFragment, I know how to How to set the title to my DialogFragment , but I want more not just a title , I need a customized title(color,fontSize ...), So I defined a TextView and customized it
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.height_fragment,container,false);
TextView title = new TextView(getContext());
title.setText("Your Height Information");
title.setGravity(Gravity.CENTER);
title.setTextSize(30);
title.setBackgroundColor(Color.GRAY);
title.setTextColor(Color.WHITE);
getDialog().setCustomTitle(title); //Error Can not resolve method setCustomTitle(android.widget.TextView)
return view;
}
but there is an error on this line
getDialog().setCustomTitle(title);
getDialog().setCustomTitle(title);
I searched a lot before posting this question but I couldn't find how can I customize my title of DialogFragment.
Thank you for taking time to help me
"getDialog" does not have a method "setCustomTitle".This method can only be used for AlertDialog.Builder. Try it like this:
getDialog().setTitle("Your Height Information");
TextView textView=(TextView) getDialog().findViewById(android.R.id.title);
textView.setTextSize(30);
I never could easily customize the Title of my DialogFragment. So, instead, I use to remove the title and add a TextView to Dialog layout (and use it like a Title). This way, you can customize how you want and easily.
Dialog Code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Remove TITLE
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
View dialogView = dialogView = inflater.inflate(R.layout.height_fragment, null);
// Do your stuff
return dialogView;
}
height_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/dialog_title"
android:layout_width="match_parent"
android:layout_height="56dp"
<!-- THIS VIEW IS YOUR TITLE... CUSTOMIZE LYKE YOU WANT -->
android:textColor="#color/white"
android:textSize="18sp"
android:textStyle="bold"
android:layout_gravity="top"
android:text="#string/TITLE"
android:gravity="center_vertical"
android:paddingLeft="16dp" />
<!-- Real Content goes below the title -->
</FrameLayout>
You need to connect your xml to your class. findViewById tells your class which TextView to use. Notice how it must match the android:id in the xml:
public class DialogFragmentTest extends DialogFragment {
public final static String TITLE = "title";
public final static String MESSAGE = "message";
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog, null);
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(view);
Bundle args = getArguments();
String title = args.getString(TITLE, "default title");
String msg = args.getString(MESSAGE, "default message");
TextView tvTitle = (TextView)view.findViewById(R.id.dialog_title);
tvTitle.setText(title);
TextView tvMessage = (TextView)view.findViewById(R.id.dialog_message);
tvMessage.setText(msg);
Button btnDone = (Button)view.findViewById(R.id.dialog_button);
btnDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
return builder.create();
}
}
dialog.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="300dp"
android:layout_height="wrap_content">
<TextView
android:id="#+id/dialog_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="title"/>
<TextView
android:id="#+id/dialog_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/dialog_title"
android:layout_marginTop="10dp"
android:text="message"/>
<Button
android:id="#+id/dialog_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/dialog_message"
android:layout_marginTop="20dp"
android:layout_centerHorizontal="true"
android:text="done"/>
</RelativeLayout>
This is then called from your activity with:
DialogFragmentTest bd = new DialogFragmentTest();
Bundle b = new Bundle();
b.putString(DialogFragmentTest.TITLE, "my title");
b.putString(DialogFragmentTest.MESSAGE, "my message");
bd.setArguments(b);
bd.show(getFragmentManager(), "my title");
Please, use custom dialog, based on DialogFragment:
public class MyCustomDialog extends DialogFragment{
private Context context;
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View dialogView = inflater.inflate(R.layout.custom_dialog, null, false);
TextView tvTitle = (TextView) getDialog().findViewById(android.R.id.title);
tvTitle.setTextSize(25);
tvTitle.setTextColor(Color.GREEN);
return dialogView;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new Dialog(this.context, R.style.CustomDialog);
dialog.setTitle("custom dialog title");
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
return dialog;
}
public static MyCustomDialog newInstance() {
MyCustomDialog myCustomDialog = new MyCustomDialog();
return myCustomDialog;
}
}
I have a problem with a Fragment.
There is a Dialog inside a Fragment, and a Fragment inside this Dialog.
But when I add the second Fragment, there is an IllegalArgumentException : No view found for id ***** (fr.*****:id/container_list_collections) for fragment FragmentCollectionVignette.
FragmentHP.java
public class FragmentHP extends Fragment {
/** Bouton Ajouter à **/
private Button btAddTo;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, final Bundle savedInstanceState) {
View vueFragmentHP = inflater.inflate(R.layout.fragment_hp, container, false);
getFragmentManager().beginTransaction().replace(R.id.container_dernier_ajout, new FragmentDerniersAjoutsHP()).commit();
getFragmentManager().beginTransaction().replace(R.id.container_collections, new FragmentCollectionsHP()).commit();
getFragmentManager().beginTransaction().replace(R.id.container_ebooks, new FragmentEbooksHP()).commit();
getFragmentManager().beginTransaction().replace(R.id.container_games, new FragmentGamesHP()).commit();
getFragmentManager().beginTransaction().replace(R.id.container_software, new FragmentSoftwareHP()).commit();
getFragmentManager().beginTransaction().replace(R.id.container_digital_creation, new FragmentDigitalCreationHP()).commit();
btAddTo = (Button) vueFragmentHP.findViewById(R.id.bt_collections);
btAddTo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_add_to, null);
final Dialog dialog = new Dialog(getActivity());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(view);
dialog.show();
dialog.setCanceledOnTouchOutside(false);
Button btValider = (Button) view.findViewById(R.id.bt_add_to);
getFragmentManager().beginTransaction().add(R.id.container_list_collections, new FragmentCollectionVignette()).commit();
}
});
return vueFragmentHP;
}
}
dialog_add_to.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tv_add_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/add_to"/>
<TextView
android:id="#+id/tv_choose_collection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/choose_collection"
android:layout_below="#id/tv_add_to"/>
<FrameLayout
android:id="#+id/container_list_collections"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/tv_choose_collection"/>
<Button
android:id="#+id/bt_add_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/valider"
android:layout_below="#id/container_list_collections"/>
</RelativeLayout>
What is the problem ?
(Sorry for my very bad english)
i think the problem is in this line
getFragmentManager()
.beginTransaction()
.add(R.id.container_list_collections, new FragmentCollectionVignette())
.commit();
change this to
this.getActivity()
.getFragmentManager()
.beginTransaction()
.add(R.id.container_list_collections, new FragmentCollectionVignette())
.commit()