在当前的Android应用程序中,有一个屏幕显示android.support.v4.app.DialogFragment
。
此DialogFragment
视图包含以下UI组件
HEADING
== Sub Heading
== NestedScrollView
==== RecyclerView
==== RadioGroup
==== Spinner
==== EditText
==== Action Buttons
使用以下样式将DialogFragment
配置为全屏显示:-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.AppDialogTheme);
}
我的对话框样式是
<!-- Define your custom dialog theme here extending from base -->
<style name="AppDialogTheme" parent="Theme.AppCompat.Light.Dialog">
<!-- Define color properties as desired -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">#000</item>
<item name="android:textColorHighlight">@color/background_url</item>
<item name="colorAccent">@color/dark_grey</item>
<item name="colorControlNormal">@color/colorPrimaryDark</item>
<!-- Define window properties as desired -->
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowBackground">@android:color/white</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowCloseOnTouchOutside">false</item>
</style>
我聘用NestedScrollView
的原因是为了使View
在纵向和横向模式下均可工作。
我希望限制height
中的RecyclerView
最接近的是使用下面的布局。
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/headline_literal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:padding="10dp"
android:text="Heading"
android:textSize="20sp"
android:textStyle="bold" />
<View
android:id="@+id/divider"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_marginTop="5dp"
android:background="#c0c0c0" />
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="5"
android:orientation="vertical">
<TextView
android:id="@+id/sub_headline_literal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="Some long texts having a long size so that it takes multiple lines in the view to replicate the real-life app use case. This is important to have 3-4 lines this textview so that we can see if the views are being populated correctly. Hope this sentence is long enough to replicate the real-life scenario of this TextView content. Thank you."
android:textSize="16sp"
android:textStyle="normal" />
<android.support.v7.widget.RecyclerView
android:id="@+id/dummy_rv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="10dp"
android:layout_marginStart="9dp"
android:layout_marginEnd="9dp"
android:layout_weight="1"
android:background="@drawable/rv_border"
android:fadingEdge="horizontal"
android:fadingEdgeLength="10dp"
android:padding="10dp"
android:requiresFadingEdge="vertical" />
<RadioGroup
android:id="@+id/myRadioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:checkedButton="@+id/sound">
<RadioButton
android:id="@+id/sound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sound" />
<RadioButton
android:id="@+id/vibration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Vibration" />
<RadioButton
android:id="@+id/silent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Silent" />
</RadioGroup>
<EditText
android:id="@+id/notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Notes" />
<LinearLayout
android:id="@+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/cancel_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Cancel" />
<TextView
android:id="@+id/submit_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Submit" />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
通过在weightSum
内部LinearLayout
上使用NestedScrollView
,我可以限制Recyclerview
的高度。但是NestedScrollView
的高度太大,超过一半的高度为空白。
如何限制RecyclerView
的高度并使NestedScrollView
变为wrap_content
?
我尝试过NestedScrollView
的高度wrap_content
,但这没有任何作用。
如何获得所需的UI?提前致谢!
答案 0 :(得分:3)
我建议不要在您的NestedRecyclerView
中添加页眉和页脚,而不是使用RecyclerView
,这样可以很好地将整体内容放到我所看到的布局中。我想为您提供一个指向my answer here的链接,您可以在其中找到如何在RecyclerView
中添加页脚和页眉。
因此,我建议使用headline_literal
和divider
创建一个视图并将其用作标题,而RadioGroup
,EditText
和{{ 1}}将位于页脚中。让我知道您是否遇到任何问题。
我已经尝试实现自己想要的行为,并让我知道以下实现是否对您有用。我也在Github中添加了它。
让我们首先声明一个适配器,用于向Button
添加页眉和页脚。
RecyclerView
现在让我们一一定义布局。这是import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
public class RecyclerViewWithHeaderFooterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int FOOTER_VIEW = 1;
private static final int HEADER_VIEW = 2;
private ArrayList<String> data; // Take any list that matches your requirement.
private Context context;
// Define a constructor
public RecyclerViewWithHeaderFooterAdapter(Context context, ArrayList<String> data) {
this.context = context;
this.data = data;
}
// Define a ViewHolder for Header view
public class HeaderViewHolder extends ViewHolder {
public HeaderViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Do whatever you want on clicking the item
}
});
}
}
// Define a ViewHolder for Footer view
public class FooterViewHolder extends ViewHolder {
public FooterViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Do whatever you want on clicking the item
}
});
}
}
// Now define the ViewHolder for Normal list item
public class NormalViewHolder extends ViewHolder {
public NormalViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Do whatever you want on clicking the normal items
}
});
}
}
// And now in onCreateViewHolder, you have to pass the correct view
// while populating the list item.
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
if (viewType == FOOTER_VIEW) {
v = LayoutInflater.from(context).inflate(R.layout.list_item_footer, parent, false);
FooterViewHolder vh = new FooterViewHolder(v);
return vh;
} else if (viewType == HEADER_VIEW) {
v = LayoutInflater.from(context).inflate(R.layout.list_item_header, parent, false);
HeaderViewHolder vh = new HeaderViewHolder(v);
return vh;
}
// Otherwise populate normal views
v = LayoutInflater.from(context).inflate(R.layout.list_item_normal, parent, false);
NormalViewHolder vh = new NormalViewHolder(v);
return vh;
}
// Now bind the ViewHolder in onBindViewHolder
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
try {
if (holder instanceof NormalViewHolder) {
NormalViewHolder vh = (NormalViewHolder) holder;
vh.bindView(position);
} else if (holder instanceof FooterViewHolder) {
FooterViewHolder vh = (FooterViewHolder) holder;
} else if (holder instanceof HeaderViewHolder) {
HeaderViewHolder vh = (HeaderViewHolder) holder;
}
} catch (Exception e) {
e.printStackTrace();
}
}
// Now the critical part. You have return the exact item count of your list
// I've only one footer. So I returned data.size() + 1
// If you've multiple headers and footers, you've to return total count
// like, headers.size() + data.size() + footers.size()
@Override
public int getItemCount() {
if (data == null) {
return 0;
}
if (data.size() == 0) {
// Return 1 here to show nothing
return 1;
}
// Add extra view to show the header view
// Add another extra view to show the footer view
// So there are two extra views need to be populated
return data.size() + 2;
}
// Now define getItemViewType of your own.
@Override
public int getItemViewType(int position) {
if (position == 0) {
// This is where we'll add the header.
return HEADER_VIEW;
} else if (position == data.size() + 1) {
// This is where we'll add a footer.
return FOOTER_VIEW;
}
return super.getItemViewType(position);
}
// So you're done with adding a footer and its action on onClick.
// Now set the default ViewHolder for NormalViewHolder
public class ViewHolder extends RecyclerView.ViewHolder {
// Define elements of a row here
public ViewHolder(View itemView) {
super(itemView);
// Find view by ID and initialize here
}
public void bindView(int position) {
// bindView() method to implement actions
}
}
}
。
list_item_normal.xml
<?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="wrap_content">
<TextView
android:id="@+id/normal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="This is a text to be displayed in each item in the RecyclerView"
android:textSize="16sp"
android:textStyle="normal" />
</LinearLayout>
应该如下所示。
list_item_footer.xml
最后,<?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="wrap_content"
android:layout_marginTop="16dp"
android:orientation="vertical">
<RadioGroup
android:id="@+id/myRadioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:checkedButton="@+id/sound">
<RadioButton
android:id="@+id/sound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sound" />
<RadioButton
android:id="@+id/vibration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Vibration" />
<RadioButton
android:id="@+id/silent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Silent" />
</RadioGroup>
<EditText
android:id="@+id/notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Notes" />
<LinearLayout
android:id="@+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/cancel_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Cancel" />
<TextView
android:id="@+id/submit_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Submit" />
</LinearLayout>
</LinearLayout>
应该具有以下内容。
list_item_header.xml
现在,您已将原始布局的组成部分分成了几个部分。因此,主要布局应如下所示。
<?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="wrap_content">
<TextView
android:id="@+id/sub_headline_literal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="Some long texts having a long size so that it takes multiple lines in the view to replicate the real-life app use case. This is important to have 3-4 lines this textview so that we can see if the views are being populated correctly. Hope this sentence is long enough to replicate the real-life scenario of this TextView content. Thank you."
android:textSize="16sp"
android:textStyle="normal" />
</LinearLayout>
因此,我要共享一个示例<?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="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/headline_literal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:padding="10dp"
android:text="Heading"
android:textSize="20sp"
android:textStyle="bold" />
<View
android:id="@+id/divider"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_marginTop="5dp"
android:background="#c0c0c0" />
<android.support.v7.widget.RecyclerView
android:id="@+id/dummy_rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp" />
</LinearLayout>
来运行此代码,该代码将显示整个实现。
Activity
希望有帮助!
答案 1 :(得分:0)
容易
使用具有特定高度的 maxHeight 属性,如果仍然无法使用,请尝试创建扩展 RecyclerView的 customrecyclerview 并使用 OnMeasure 方法覆盖高度。
答案 2 :(得分:0)
自定义回收者视图以设置ThreadingMixIn
。
maxHeight
n attrs.xml
public class MaxHeightRecyclerView extends RecyclerView {
private int mMaxHeight;
public MaxHeightRecyclerView(Context context) {
super(context);
}
public MaxHeightRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context, attrs);
}
public MaxHeightRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context, attrs);
}
private void initialize(Context context, AttributeSet attrs) {
TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
mMaxHeight = arr.getLayoutDimension(R.styleable.MaxHeightScrollView_maxHeight, mMaxHeight);
arr.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mMaxHeight > 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxHeight, MeasureSpec.AT_MOST);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
在xml中将RecyclerView高度<declare-styleable name="MaxHeightScrollView">
<attr name="maxHeight" format="dimension" />
</declare-styleable>
和maxHeight设置为dp中的fixwidth。
RecyclerView将消耗高度wrap_content直到您设置的fixWidth,达到maxHeight后,RecyclerView将可滚动。
答案 3 :(得分:0)
如果您还需要通过制作自定义的NestedScrollView来限制NestedScrollView的大小:
public class CustomNestedScrollView extends NestedScrollView {
private int maxHeight;
private final int defaultHeight = 200;
public CustomNestedScrollView(Context context) {
super(context);
}
public CustomNestedScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
if (!isInEditMode()) {
init(context, attrs);
}
}
public CustomNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (!isInEditMode()) {
init(context, attrs);
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
if (!isInEditMode()) {
init(context, attrs);
}
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.CustomNestedScrollView);
//200 is a defualt value
maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.CustomNestedScrollView_maxHeight, defaultHeight);
styledAttrs.recycle();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
attr.xml
<declare-styleable name="CustomNestedScrollView">
<attr name="maxHeight" format="dimension" />
</declare-styleable>
自定义NestedScrollView的示例布局:
<your.package.CustomNestedScrollView
android:layout_weight="1"
app:maxHeight="90dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!--Child view with RecyclerView here-->
</your.package.CustomNestedScrollView>
与此自定义NestedScrollView一起使用,如果您应用RecyclerView的自定义,那么它将完全按照您想要的方式工作。我希望这会有所帮助!