我在Android中构建了一个易于构建和构建的构造。在屏幕上显示DialogFragment。 该对话框包含TextView,ListView和Button。 它可以轻松地在ListView中扩展不同的视图,因此我可以创建自定义对话框。
左图是正确的。在右边,我夸大了一个额外的视图。我用来在DialogFragment中显示文本的视图。但是当我添加该视图时,它不再包装内容。 ListView使其自身可滚动。
我可以添加更多您在图像上看到的蓝色按钮,ListView仍然会正确包装内容。但是当我添加一个或多个其他视图时,ListView使其自身可滚动。
问题是我无法让ListView以wrap_content正确。
这是“蓝色按钮”视图的xml :(正确的膨胀视图)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/overlay_item_label"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:weightSum="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/tile_button_categorytile"
android:orientation="horizontal">
<ImageView
android:id="@+id/popUpImage"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="6dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_speaker" />
<com.joanzapata.iconify.widget.IconTextView
android:id="@+id/popUpButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="4dp"
android:layout_marginRight="15dp"
android:layout_weight="1"
android:padding="4dp"
android:text="Bewerken {fa-android}"
android:textColor="@color/white"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
在DialogFragment中用作文本的视图:(导致ListView使其自身可滚动)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/overlay_item_label"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/white"
android:layout_weight="1"
android:weightSum="1">
<TextView
android:id="@+id/LabelOverlay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_gravity="center"
android:gravity="center"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="@string/placeholder"
android:textColor="@color/purple"
android:textSize="12sp" />
</LinearLayout>
当我向用于显示文本的视图添加额外的paddingTop和paddingBottom时,ListView不会使其自身可滚动(仅在少数设备上)。填充设置为大约20dp然后在某些设备上它不会使自己可滚动,但在其他设备上它的填充太多,所以它显示空白...
这是显示DialogFragment的片段代码:
public class PopUpFragmentPhone extends DialogFragment {
PopUp popUpData;
ListView listView;
public static PopUpFragmentPhone newInstance(PopUp data) {
PopUpFragmentPhone popUpFragment = new PopUpFragmentPhone();
Bundle args = new Bundle();
args.putParcelable("PopUpData", data);
popUpFragment.setArguments(args);
return popUpFragment;
}
@Override
public void onStart(){
super.onStart();
Window window = getDialog().getWindow();
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.dimAmount = 0.70f;
windowParams.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
window.setAttributes(windowParams);
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
getDialog().getWindow().setLayout(MainApplication.width / 2, ViewGroup.LayoutParams.WRAP_CONTENT);
getDialog().setCanceledOnTouchOutside(true);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme);
popUpData = getArguments().getParcelable("PopUpData"); //get the PopUp class.
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.pop_up_phone, container, false);
//Set the title of the popUp
TextView popUpTitle = (TextView)v.findViewById(R.id.overlayTitle);
popUpTitle.setText(popUpData.getHeader());
listView = (ListView) v.findViewById(R.id.listViewItemsOverlay);
listView.setAdapter(new PopUpAdapterPhone(MainApplication.getContext(), 1, popUpData.getItems(), this));
boolean showCancel = popUpData.isCancel();
Button cancelButton = (Button) v.findViewById(R.id.cancel_button);
Drawable cancelIcon = new IconDrawable(getActivity(), FontAwesomeIcons.fa_times).colorRes(R.color.red).sizeDp(20);
cancelButton.setCompoundDrawablesWithIntrinsicBounds(cancelIcon, null, null, null);
if(showCancel) {
// Cancel button click
cancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getDialog().dismiss();
}
});
} else {
cancelButton.setVisibility(View.GONE);
}
getDialog().getWindow().setLayout(MainApplication.width / 2, ViewGroup.LayoutParams.WRAP_CONTENT);//set the size of the fragment, so the rest is a touch to cancel the popUP
return v;
}
}
弹出片段的视图:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="5dp"
android:weightSum="3"
android:background="@drawable/tile_button_wordtile"
android:id="@+id/overlay_master_view">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/menu"
android:id="@+id/overlayTitle"
android:textStyle="bold"
android:textSize="15sp"
android:padding="4dp"
android:textColor="@color/purple"
android:layout_weight="1"
android:background="@color/white"
android:layout_margin="4dp"
android:layout_gravity="center_horizontal" />
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:layout_weight="1"
android:divider="@android:color/transparent"
android:dividerHeight="5.0sp"
android:id="@+id/listViewItemsOverlay">
</ListView>
<com.joanzapata.iconify.widget.IconButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:padding="5dp"
android:layout_weight="1"
android:textStyle="bold"
android:textSize="15sp"
android:drawablePadding="5dp"
android:id="@+id/cancel_button"
android:layout_marginTop="5dp"
android:textColor="@color/red"
android:background="@drawable/tile_button_functiontile"
android:text="@string/cancel"/>
</LinearLayout>
我尝试了很多东西,在LinearLayout或RelativeLayout中充气。 Wrap_content,match_parent,weightSum和所有类型的东西。尝试在很多方面改变布局,但一切都没有成功。
我希望有人可以帮助我。
答案 0 :(得分:1)
注意:在下面的代码中,我删除了背景,因为我没有。
但基本上你不应该过多地改变它以匹配你想要的东西。
您的对话
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.view.WindowManager;
import android.widget.ListView;
import java.util.ArrayList;
public class CustomDialogFragment extends DialogFragment {
private static final String DIALOG_DATA = "my.app.package.DIALOG_DATA";
public static CustomDialogFragment newInstance(ArrayList<ListElement> data) {
CustomDialogFragment f = new CustomDialogFragment();
Bundle args = new Bundle();
args.putParcelableArrayList(DIALOG_DATA, data);
f.setArguments(args);
return f;
}
@Override
public void onResume() {
super.onResume();
// Calculate the height/width you want
// See: https://stackoverflow.com/a/12923805/1827254 for more info
// In this example, the width is not changed as retrieved from the LayoutParams of the dialog.
WindowManager.LayoutParams params = getDialog().getWindow().getAttributes();
int width = params.width; //getResources().getDimensionPixelSize(R.dimen.popup_width);
int height = getResources().getDimensionPixelSize(R.dimen.popup_height);
getDialog().getWindow().setLayout(width, height);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
ArrayList<ListElement> data = getArguments().getParcelableArrayList(DIALOG_DATA);
// Inflate the dialog layout
View view = View.inflate(getContext(), R.layout.custom_dialog, null);
ListView listView = view.findViewById(R.id.dialog_list);
listView.setAdapter(new CustomAdapter(getContext(), data));
View btn = view.findViewById(R.id.dialog_cancel_button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss(); // Dismiss the dialog.
}
});
return new AlertDialog.Builder(getActivity())
.setView(view)
.create();
}
}
对话框布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/overlay_master_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">
<!-- Title of the view -->
<!-- Note: instead of using 'android:text="@string/placehoder"' use
'tools:text="My preview text"'. Otherwise the system has to set your
placeholder value and then replace it with the actual value you want in the code -->
<TextView
android:id="@+id/dialog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@color/white"
android:padding="4dp"
android:text="@string/menu"
android:textColor="@color/purple"
android:textSize="15sp"
android:textStyle="bold"
tools:text="Preview text" />
<!-- The ListView needs to have a height of 0 in order to let
the button to be displayed below it-->
<ListView
android:id="@+id/dialog_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="@android:color/transparent"
android:dividerHeight="5.0sp"
android:scrollbars="none" />
<!-- Button 'cancel'-->
<com.joanzapata.iconify.widget.IconButton
android:id="@+id/dialog_cancel_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:drawablePadding="5dp"
android:gravity="start"
android:padding="5dp"
android:text="@string/cancel"
android:textColor="@color/red"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
列表适配器
class CustomAdapter extends ArrayAdapter<ListElement> {
private final LayoutInflater mInflater;
public CustomAdapter(Context context, ArrayList<ListElement> data) {
super(context, 0, data);
mInflater = LayoutInflater.from(context);
}
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
// Get the data item for this position
ListElement element = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
// Use your custom layout
convertView = mInflater.inflate(R.layout.list_element, parent, false);
}
// Get the views and set the data
TextView tv = (TextView) convertView.findViewById(R.id.elt_text);
tv.setText(element.getText());
ImageView imageView = (ImageView) convertView.findViewById(R.id.elt_image);
imageView.setImageResource(element.getIconRes());
return convertView;
}
}
列出元素布局
我认为为每个组件设置权重是您的一个问题
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/overlay_item_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/blue"
android:orientation="horizontal">
<ImageView
android:id="@+id/elt_image"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="6dp"
android:scaleType="fitCenter"
tools:src="@mipmap/ic_launcher" />
<com.joanzapata.iconify.widget.IconTextView
android:id="@+id/elt_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="4dp"
android:layout_marginRight="15dp"
android:padding="4dp"
android:textColor="@color/white"
android:textSize="14sp"
android:textStyle="bold"
tools:text="Bewerken {fa-android}" />
</LinearLayout>
列表中的元素
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.DrawableRes;
/**
* Every element of the list has an icon and a text.
* You can add other parameters
*/
public class ListElement implements Parcelable {
private String mText;
@DrawableRes
private Integer mIconRes;
public ListElement() {
// Default constructor
}
public ListElement(String text, @DrawableRes int resId) {
this.mText = text;
this.mIconRes = resId;
}
protected ListElement(Parcel in) {
mText = in.readString();
if (in.readByte() == 0) {
mIconRes = null;
} else {
mIconRes = in.readInt();
}
}
public static final Creator<ListElement> CREATOR = new Creator<ListElement>() {
@Override
public ListElement createFromParcel(Parcel in) {
return new ListElement(in);
}
@Override
public ListElement[] newArray(int size) {
return new ListElement[size];
}
};
public String getText() {
return mText;
}
public Integer getIconRes() {
return mIconRes;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(mText);
if (mIconRes == null) {
parcel.writeByte((byte) 0);
} else {
parcel.writeByte((byte) 1);
parcel.writeInt(mIconRes);
}
}
}
用例示例(在MainActivity中)
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ArrayList<ListElement> data = generateData();
// Create and show the dialog.
DialogFragment newFragment = CustomDialogFragment.newInstance(data);
newFragment.show(ft, "dialog");
}
private ArrayList<ListElement> generateData() {
ArrayList<ListElement> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(new ListElement("elt " + i, R.mipmap.ic_launcher));
}
return list;
}
}