当 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 行项目中包含隐藏视图时,片段不尊重匹配父高度的主要内容,如果未能解决你的问题,请参考以下文章

更新 ListView 中的特定项目

多个视图与多个片段

Android中包含Header和Footer的无限ListView的实现

Flutter中包含GridViews和ListViews的ListView

在 listview 类方法中包含业务逻辑的位置

选择按钮时隐藏视图和其他对象