当 listview 行项目中包含隐藏视图时,片段不尊重匹配父高度
Posted
技术标签:
【中文标题】当 listview 行项目中包含隐藏视图时,片段不尊重匹配父高度【英文标题】:Fragment doesn't respect match parent height when having listview row item has hidden view in it 【发布时间】:2016-05-02 04:46:33 【问题描述】:我的应用出现了一个奇怪的问题。在我的一个应用程序活动中,我用标签填充了其中的三个片段。一切正常。
在我遇到问题的片段中,我有使用适配器和来自 Web 服务的数据膨胀的列表视图。这也很有效。现在的问题是适配器中膨胀的行,有一个隐藏视图,在 xml 中有visibility=gone
。在从该行中点击 imageview 时,我通过 java 代码使该布局可见。问题是布局在点击时不可见。 我什至在 imageview 的 onClickListener 上设置了断点,它确实执行了将可见性从消失变为可见的行。我无法理解是什么导致了这个问题,因为我在其他屏幕中使用具有相同数据的同一行 xml,并且它运行良好。
更新
我知道是什么导致了这个问题,但不知道如何解决这个问题。在我的活动中,我有三个片段。我为片段(片段将被膨胀)提供的视图导致了主要问题。我已将高度宽度设置为匹配父级,但它没有匹配父级高度。如果片段只包含文本视图、图像视图等普通视图,那么片段也会正确显示。但问题是如果片段由列表视图组成,那么它只需要提供给列表视图的自定义行的高度。我能够在该空间中滚动完整的列表视图。 我不明白是什么导致了这种行为。 我的更新代码。
主布局xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<include layout="@layout/header_1" />
<LinearLayout
android:layout_
android:layout_
android:background="#000"
android:weightSum="3"
android:orientation="horizontal">
<LinearLayout
android:layout_
android:layout_
android:layout_weight="1"
android:weightSum="1"
android:orientation="horizontal"
android:id="@+id/lin_birds">
<TextView
android:layout_
android:layout_
android:text="@string/aves"
android:textColor="#ffffff"
android:gravity="center"
android:layout_gravity="center"
android:layout_weight="0.99"
android:id="@+id/fragment_aves"/>
<View
android:layout_
android:layout_
android:layout_weight="0.01"
android:background="#ffffff"
android:layout_marginTop="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:layout_weight="1"
android:weightSum="1"
android:orientation="horizontal">
<TextView
android:layout_
android:layout_
android:text="@string/routes"
android:textColor="#ffffff"
android:gravity="center"
android:layout_gravity="center"
android:layout_weight="0.99"
android:id="@+id/fragment_routes"/>
<View
android:layout_
android:layout_
android:layout_weight="0.01"
android:background="#ffffff"
android:layout_marginTop="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_
android:layout_
android:text="@string/information"
android:textColor="#ffffff"
android:gravity="center"
android:layout_gravity="center"
android:id="@+id/fragment_information"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<FrameLayout
android:layout_
android:layout_
android:id="@+id/frame_details" />
</LinearLayout>
</LinearLayout>
主要活动java代码
public class ActivityRoutesDetails extends AppCompatActivity
RelativeLayout rel_back;
TextView tv_title,tv_information,tv_routes,fragment_aves;
RoutesDataBean routesDataBean;
LinearLayout frame;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.routes_detail);
tv_title= (TextView)findViewById(R.id.tv_title);
tv_information= (TextView) findViewById(R.id.fragment_information);
tv_routes= (TextView) findViewById(R.id.fragment_routes);
fragment_aves= (TextView) findViewById(R.id.fragment_aves);
// frame= (LinearLayout) findViewById(R.id.frame_details);
routesDataBean= (RoutesDataBean)getIntent().getSerializableExtra("data");
tv_title.setText(routesDataBean.getDescrip1());
Fragment fragment=new FragmentRouteInside();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_details, fragment);
fragmentTransaction.commit();
fragment_aves.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Fragment fragmentBirds=new FragmentRouteBirds();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_details, fragmentBirds);
fragmentTransaction.commit();
);
tv_information.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Fragment fragmentRouteInformation = new FragmentRouteInformation();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_details, fragmentRouteInformation);
fragmentTransaction.commit();
);
tv_routes.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Fragment fragment=new FragmentRouteInside();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_details, fragment);
fragmentTransaction.commit();
);
rel_back= (RelativeLayout) findViewById(R.id.rel_back);
rel_back.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
finish();
);
片段鸟xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:id="@+id/lv_bird"/>
</LinearLayout>
片段java代码
public class FragmentRouteBirds extends Fragment
AppSharedPreferences appSharedPreferences;
String REGISTER_URL="";
ListView lv_birds;
private ArrayList<BirdsDataBean> birdsUrlList;
boolean flag=false;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragments_birds, null);
appSharedPreferences=AppSharedPreferences.getsharedprefInstance(getActivity());
REGISTER_URL = "http://192.241.162.63/appvist/v1/routebird/"+appSharedPreferences.getRouteId();
birdsUrlList = new ArrayList<>();
lv_birds = (ListView) root.findViewById(R.id.lv_bird);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) lv_birds.getLayoutParams();
lp.height = LinearLayout.LayoutParams.MATCH_PARENT;
lv_birds.setLayoutParams(lp);
hitBirdsService();
return root;
private void hitBirdsService()
class RegisterUser extends AsyncTask<String, Void, String>
private ProgressDialog mDialog;
RequestClass ruc = new RequestClass();
String response = "";
@Override
protected void onPreExecute()
super.onPreExecute();
mDialog = new ProgressDialog(getActivity());
mDialog.setMessage("Please Wait ...");
mDialog.setCancelable(false);
mDialog.show();
@Override
protected void onPostExecute(String s)
super.onPostExecute(s);
mDialog.dismiss();
parseBirdResponse(response);
//Toast.makeText(getActivity(), s, Toast.LENGTH_LONG).show();
@Override
protected String doInBackground(String[] params)
response = RequestClass.GET(REGISTER_URL);
return response;
RegisterUser ru = new RegisterUser();
ru.execute();
public void parseBirdResponse(String response)
//String descrip, String observaciones, String descrip_larga, String url_video, String url
try
JSONObject jsonObject = new JSONObject(response);
Boolean error = jsonObject.getBoolean("error");
if (!error)
JSONArray jsonArray = jsonObject.getJSONArray("birds");
for (int i = 0; i < jsonArray.length(); i++)
JSONObject jsonBirds = jsonArray.getJSONObject(i);
int idave=jsonBirds.getInt("idave");
String descrip = jsonBirds.getString("descrip");
String observaciones = jsonBirds.getString("observaciones");
String descrip_larga = jsonBirds.getString("descrip_larga");
String url_video = jsonBirds.getString("url_video");
String url = jsonBirds.getString("url");
String nombre_cientifico = jsonBirds.getString("nombre_cientifico");
int flag=jsonBirds.getInt("flag");
birdsUrlList.add(new BirdsDataBean(flag,idave,descrip, observaciones, descrip_larga, url_video, url, nombre_cientifico));
ScheduleTaskAdapter scheduleTaskAdapter = new ScheduleTaskAdapter(getActivity(), birdsUrlList);
lv_birds.setAdapter(scheduleTaskAdapter);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) lv_birds.getLayoutParams();
lp.height = 800;
lv_birds.setLayoutParams(lp);
catch (JSONException e)
e.printStackTrace();
public class ScheduleTaskAdapter extends BaseAdapter
Context context;
LayoutInflater layoutInflater;
// List<InterestAndLanguageBean> interestAndLanguageBeans=new ArrayList<>();
List<BirdsDataBean> imageList = new ArrayList<>();
public ScheduleTaskAdapter(Context context, List<BirdsDataBean> imagesList)
this.context = context;
this.imageList = imagesList;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@Override
public int getCount()
return imageList.size();
@Override
public Object getItem(int position)
return null;
@Override
public long getItemId(int position)
return 0;
@Override
public View getView(final int position, View convertView, ViewGroup parent)
ViewHolder holder = null;
if (convertView == null)
holder = new ViewHolder();
convertView = layoutInflater.inflate(R.layout.routes_bird_row, parent, false);
holder.iv_birds = (ImageView) convertView.findViewById(R.id.iv_route_bird);
holder.frameLayout = (FrameLayout) convertView.findViewById(R.id.frame_route_bird);
holder.linearLayout = (LinearLayout) convertView.findViewById(R.id.route_bird_detail_view);
holder.imageView = (ImageView) convertView.findViewById(R.id.iv_hide);
holder.iv_video = (ImageView) convertView.findViewById(R.id.iv_seen);
holder.iv_sound = (ImageView) convertView.findViewById(R.id.iv_video);
holder.tv_short_descript = (TextView) convertView.findViewById(R.id.tv_bird_name);
holder.tv_category = (TextView) convertView.findViewById(R.id.tv_scientific_name);
holder.tv_long_description = (TextView) convertView.findViewById(R.id.tv_description);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
Uri myUri = Uri.parse(birdsUrlList.get(position).getUrl());
Glide.with(getActivity()).load(myUri).placeholder(R.drawable.birds).into(holder.iv_birds);
holder.tv_short_descript.setText(birdsUrlList.get(position).getDescrip());
holder.tv_long_description.setText(birdsUrlList.get(position).getDescrip_larga());
holder.tv_category.setText(birdsUrlList.get(position).getNombre_cientifico());
final ViewHolder finalHolder = holder;
holder.frameLayout.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
finalHolder.linearLayout.setVisibility(View.VISIBLE);
finalHolder.iv_sound.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
try
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(birdsUrlList.get(position).getUrl_video())));
catch (ActivityNotFoundException e)
e.printStackTrace();
);
finalHolder.iv_video.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
//hitBirdSeenService(birdsUrlList.get(position).getIdave());
// finalHolder.iv_video.setImageResource(R.drawable.eye_selected);
);
);
holder.imageView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
finalHolder.linearLayout.setVisibility(View.GONE);
);
//Picasso.with(context).load(myUri).placeholder(R.drawable.image).into(holder.pic);
//malevich.load(helperTaskBeanList.get(position).getImage()).into(holder.pic);
return convertView;
static class ViewHolder
ImageView iv_birds,imageView,iv_video,iv_sound;
FrameLayout frameLayout;
LinearLayout linearLayout;
TextView tv_short_descript,tv_category,tv_long_description;
适配器的行布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical">
<FrameLayout
android:layout_
android:layout_
android:id="@+id/frame_route_bird"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:layout_
android:layout_
android:scaleType="fitXY"
android:id="@+id/iv_route_bird"/>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
android:layout_gravity="bottom"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp" >
<TextView
android:layout_
android:layout_
android:textColor="#ffffff"
android:text="@string/name"
android:textSize="24sp"
android:textStyle="bold"
android:id="@+id/tv_bird_name"/>
<TextView
android:layout_
android:layout_
android:textSize="15sp"
android:textColor="#ffffff"
android:text="@string/bird_sub_category"
android:id="@+id/tv_scientific_name"/>
</LinearLayout>
</FrameLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
android:visibility="gone"
android:background="#ffffff"
android:id="@+id/route_bird_detail_view"
android:paddingBottom="120dp">
<TextView
android:layout_
android:layout_
android:text="@string/bird_hidden_text"
android:textSize="20sp"
android:padding="20dp"
android:id="@+id/tv_description"/>
<LinearLayout
android:layout_
android:layout_
android:orientation="horizontal"
android:layout_gravity="center">
<ImageView
android:layout_
android:layout_
android:src="@drawable/eye110"
android:id="@+id/iv_seen"/>
<ImageView
android:layout_
android:layout_
android:src="@drawable/right"
android:layout_marginTop="25dp"
android:layout_marginLeft="15dp"
android:id="@+id/iv_arrow"/>
<ImageView
android:layout_
android:layout_
android:src="@drawable/ear"
android:layout_marginLeft="15dp"
android:id="@+id/iv_video"/>
</LinearLayout>
<ImageView
android:layout_
android:layout_
android:background="#D6D6D6"
android:layout_marginTop="20dp"
android:src="@drawable/up"
android:layout_gravity="center"
android:id="@+id/iv_hide"/>
</LinearLayout>
</LinearLayout>
这里是问题截图
比较两个图像,您可以看到隐藏视图出现在单行项目的空间中,并且可以在该空间中完全滚动。
【问题讨论】:
【参考方案1】:针对 android 开发人员(Cristophe Beils)的加号目标是更好的结果:
"您的 ListView 必须将其高度设置为 match_parent 或固定大小,而不是 wrap_content。
如果你需要添加另一个固定在ListView底部的view作为footer,你需要把ListView和footer View都放在一个垂直的LinearLayout中,并且在ListView上设置layout_height为0dp,layout_weight为1,这样它占用了剩余的垂直空间。”
【讨论】:
谢谢你救了我。你的答案的下一部分做到了。我在线性布局中添加了 listview 并给它 weightsum=1 然后给 listview weight =1 它现在正在工作。非常感谢。【参考方案2】:在列表视图上尝试 fillViewPort=true.. 但不确定为什么 yoi 在列表视图中有滚动视图.. 也可能是问题。
【讨论】:
fillView 端口确实可以工作,但由于展开时列表项的高度大于屏幕尺寸,其余部分被剪切而不显示 scrollview 不是问题我已经测试过添加/删除它没有区别 为什么不试试 fillViewPort=true 并移除滚动视图。将线性布局的高度设置为填充内容。 listview 没有 fillViewPort 方法。它仅适用于滚动视图 我的错误.. 等等.. 你有一个滚动视图,在列表视图行内,列表在滚动视图内?【参考方案3】:尝试将match_parent
设置为列表视图的高度
我怀疑这会强制列表视图具有定义的高度并解决您的问题。
【讨论】:
没什么区别以上是关于当 listview 行项目中包含隐藏视图时,片段不尊重匹配父高度的主要内容,如果未能解决你的问题,请参考以下文章
Android中包含Header和Footer的无限ListView的实现