Android 可滚动布局
Posted
技术标签:
【中文标题】Android 可滚动布局【英文标题】:Android scrollable layout 【发布时间】:2016-12-02 03:42:28 【问题描述】:我想将按钮放在 ListView 下方,并将所有内容都放在 ScrollView 中(不仅 ListView 应该是可滚动的,而且按钮也是如此,所以如果 ListView 有很多元素,按钮是不可见的,用户必须向下滚动才能单击它)。
我的 xml 是:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context="com.plan.aplikacjamobilna.fragments.tabs.Allergies">
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
android:layout_gravity="center_horizontal">
<ListView
android:id="@+id/allergies_listView"
android:layout_
android:layout_
android:dividerHeight="3dp"
android:divider="#cccccc">
</ListView>
<Button
android:layout_
android:layout_
android:text="Button"/>
</LinearLayout>
</ScrollView>
看起来像:
我不知道为什么它不起作用,有“match_parent”作为layout_hight。 我应该在我的代码中更改什么?
我的适配器:
public class AllergiesAdapter extends ArrayAdapter
List list = new ArrayList();
char[] keys;
public AllergiesAdapter(Context context, int resource)
super(context, resource);
public static class DataHandler
ImageView allergieIcon;
ImageView showDetailsIcon;
TextView allergieName;
FrameLayout detailsLayout;
RelativeLayout infoLayout;
CheckBox checkBox;
@Override
public void add(Object object)
super.add(object);
list.add(object);
@Override
public int getCount()
return this.list.size();
@Override
public Object getItem(int position)
return this.list.get(position);
@Override
public View getView(final int position, View convertView, ViewGroup parent)
View view = convertView;
final DataHandler dataHandler;
if(convertView==null)
LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.allergie_item,parent,false);
dataHandler = new DataHandler();
dataHandler.allergieIcon = (ImageView) view.findViewById(R.id.allerie_icon);
dataHandler.showDetailsIcon = (ImageView) view.findViewById(R.id.allergie_show_info);
dataHandler.allergieName =(TextView) view.findViewById(R.id.allerie_name);
dataHandler.detailsLayout=(FrameLayout)view.findViewById(R.id.allergie_frameLayout);
dataHandler.infoLayout=(RelativeLayout)view.findViewById(R.id.info_layout);
dataHandler.checkBox=(CheckBox)view.findViewById(R.id.allergie_checkbox);
view.setTag(dataHandler);
else
dataHandler=(DataHandler) view.getTag();
LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final AllergiesDataProvider allergiesDataProvider;
allergiesDataProvider = (AllergiesDataProvider) this.getItem(position);
dataHandler.allergieIcon.setImageResource(allergiesDataProvider.getAllergieIcon());
dataHandler.showDetailsIcon.setImageResource(allergiesDataProvider.getShowDetailsIcon());
dataHandler.allergieName.setText(allergiesDataProvider.getAllergieName());
dataHandler.showDetailsIcon.setImageResource(allergiesDataProvider.getShowDetails());
allergiesData = getContext().getSharedPreferences("allergiesData", Context.MODE_PRIVATE);
allergiesEditor = allergiesData.edit();
String myKey = allergiesData.getString(ALLERIES_KEY,"00000000");
keys = myKey.toCharArray();
if(keys[position]=='0')
dataHandler.checkBox.setChecked(false);
else
dataHandler.checkBox.setChecked(true);
dataHandler.infoLayout.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// Toast.makeText(getContext(),"no elo",Toast.LENGTH_LONG).show();
if (!allergiesDataProvider.isDetailsShows())
allergiesDataProvider.setIsDetailsShows(true);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
dataHandler.detailsLayout.removeAllViews();
dataHandler.detailsLayout.addView(inflater.inflate(allergiesDataProvider.getDetailsLayout(), dataHandler.detailsLayout, false));
dataHandler.showDetailsIcon.setImageResource(allergiesDataProvider.getHindDetails());
else
allergiesDataProvider.setIsDetailsShows(false);
dataHandler.detailsLayout.removeAllViews();
dataHandler.showDetailsIcon.setImageResource(allergiesDataProvider.getShowDetails());
);
dataHandler.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
if (isChecked)
keys[position] = '1';
else
keys[position] = '0';
String myString = String.valueOf(keys);
allergiesEditor.putString(ALLERIES_KEY,myString).apply();
//Toast.makeText(getContext(),allergiesData.getString(ALLERIES_KEY,"Sd"),Toast.LENGTH_LONG).show();
);
return view;
【问题讨论】:
【参考方案1】:您可以使用此功能根据您的孩子设置列表视图的高度。
public static void setListViewHeightBasedOnChildren(ListView listView)
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
// pre-condition
return;
int totalHeight = 0;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
for (int i = 0; i < listAdapter.getCount(); i++)
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += listItem.getMeasuredHeight();
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
例子:
setListViewHeightBasedOnChildren(yourlistview);
【讨论】:
【参考方案2】:ListView 可以自行滚动,不应包含在 ScrollView 中。为了您的使用,您应该做的是简单地让 ListView 保持原样,并将按钮作为 ListView 中的最后一个视图。您必须修改适配器中的 getview() 方法才能实现此目的。根据索引,您将返回一个显示 Button 的视图。
【讨论】:
我编辑了我的帖子并将适配器的代码放在那里,你能解释一下如何制作这个效果吗?【参考方案3】:我建议你像这样使用RecyclerView with footer作为按钮,也可以试试HFRecyclerView
public class HeaderFooterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private static final int TYPE_FOOTER = 2;
ArrayList<Generic> generics;
Context context;
public HeaderFooterAdapter(Context context, ArrayList<Generic> generics)
this.context = context;
this.generics = generics;
@Override
public RecyclerView.ViewHolder onCreateViewHolder (ViewGroup parent, int viewType)
if(viewType == TYPE_HEADER)
View v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.header_item, parent, false);
return new HeaderViewHolder (v);
else if(viewType == TYPE_FOOTER)
View v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.footer_item, parent, false);
return new FooterViewHolder (v);
else if(viewType == TYPE_ITEM)
View v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.list_item, parent, false);
return new GenericViewHolder (v);
return null;
private Generic getItem (int position)
return generics.get (position);
@Override
public void onBindViewHolder (RecyclerView.ViewHolder holder, int position)
if(holder instanceof HeaderViewHolder)
HeaderViewHolder headerHolder = (HeaderViewHolder) holder;
headerHolder.txtTitleHeader.setText ("Header");
headerHolder.txtTitleHeader.setOnClickListener (new View.OnClickListener ()
@Override
public void onClick (View view)
Toast.makeText (context, "Clicked Header", Toast.LENGTH_SHORT).show ();
);
else if(holder instanceof FooterViewHolder)
FooterViewHolder footerHolder = (FooterViewHolder) holder;
footerHolder.txtTitleFooter.setText ("Footer");
footerHolder.txtTitleFooter.setOnClickListener (new View.OnClickListener ()
@Override
public void onClick (View view)
Toast.makeText (context, "Clicked Footer", Toast.LENGTH_SHORT).show ();
);
else if(holder instanceof GenericViewHolder)
Generic currentItem = getItem (position - 1);
GenericViewHolder genericViewHolder = (GenericViewHolder) holder;
genericViewHolder.txtName.setText (currentItem.getName ());
// need to override this method
@Override
public int getItemViewType (int position)
if(isPositionHeader (position))
return TYPE_HEADER;
else if(isPositionFooter (position))
return TYPE_FOOTER;
return TYPE_ITEM;
private boolean isPositionHeader (int position)
return position == 0;
private boolean isPositionFooter (int position)
return position == generics.size () + 1;
@Override
public int getItemCount ()
return generics.size () + 2;
class FooterViewHolder extends RecyclerView.ViewHolder
TextView txtTitleFooter;
public FooterViewHolder (View itemView)
super (itemView);
this.txtTitleFooter = (TextView) itemView.findViewById (R.id.txtFooter);
class HeaderViewHolder extends RecyclerView.ViewHolder
TextView txtTitleHeader;
public HeaderViewHolder (View itemView)
super (itemView);
this.txtTitleHeader = (TextView) itemView.findViewById (R.id.txtHeader);
class GenericViewHolder extends RecyclerView.ViewHolder
TextView txtName;
public GenericViewHolder (View itemView)
super (itemView);
this.txtName = (TextView) itemView.findViewById (R.id.txtName);
【讨论】:
以上是关于Android 可滚动布局的主要内容,如果未能解决你的问题,请参考以下文章