具有动态高度行的ListView,在滚动上闪烁

时间:2014-12-25 20:15:39

标签: android android-layout

在我提出问题之前,这里是对代码的引用:

项目代码:https://github.com/paimonsoror/RX8Club.com-Forum-Application

UI框架代码(幻灯片导航,右侧有内容):

<android.support.v4.widget.DrawerLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<ListView android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"
    android:background="#111"/>
 </android.support.v4.widget.DrawerLayout>

内容的列表视图:

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="@+id/content_parent">

    <TextView 
        android:id="@+id/mainlisttitle"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/threadTitlePlaceholder"
        android:background="#0000ff"
        android:textSize="10dip"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:gravity="center"
        android:visibility="gone"
        />

    <!--  <com.normalexception.forum.rx8club.view.PTRListView -->
    <ListView
        android:id="@+id/mainlistview"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:divider="#b5b5b5"
        android:dividerHeight="1dp"
        android:fadingEdgeLength="0dp"
        android:background="@android:color/darker_gray" />
 </LinearLayout>

项目的视图对象:

import java.util.List;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.text.Html;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.normalexception.app.rx8club.Log;
import com.normalexception.app.rx8club.MainApplication;
import com.normalexception.app.rx8club.R;
import com.normalexception.app.rx8club.WebUrls;
import com.normalexception.app.rx8club.cache.Cache;
import com.normalexception.app.rx8club.dialog.ReportPostDialog;
import com.normalexception.app.rx8club.fragment.FragmentUtils;
import com.normalexception.app.rx8club.fragment.pm.NewPrivateMessageFragment;
import com.normalexception.app.rx8club.fragment.thread.EditPostFragment;
import com.normalexception.app.rx8club.fragment.thread.ThreadFragment;
import com.normalexception.app.rx8club.handler.AvatarLoader;
import com.normalexception.app.rx8club.html.LoginFactory;
import com.normalexception.app.rx8club.preferences.PreferenceHelper;
import com.normalexception.app.rx8club.utils.Utils;

public class PostView extends RelativeLayout {
    private AvatarLoader imageLoader; 

    private TextView username;
    private TextView userTitle;
    private TextView userPosts;
    private TextView userJoin;
    private TextView postDate;
    private TextView likeText;
    private TextView postBox;

    private ImageView reportbutton;
    private ImageView linkbutton;
    private ImageView downButton;
    private ImageView avatar;
    private ImageView quoteButton;
    private ImageView editButton;
    private ImageView pmButton;
    private ImageView deleteButton;

    private WebView postText;

    private Logger TAG =  LogManager.getLogger(this.getClass());

    public PostView(Context context) {
        super(context);
        LayoutInflater.from(context).inflate(R.layout.view_newreply_children, this, true);
        imageLoader=new AvatarLoader(context);
        setupChildren();
    }

    public PostView(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.view_newreply_children, this, true);
        imageLoader=new AvatarLoader(context);
        setupChildren();
    }

    public PostView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        LayoutInflater.from(context).inflate(R.layout.view_newreply_children, this, true);
        imageLoader=new AvatarLoader(context);
        setupChildren();
    }

    /**
     * Setup the children we contain in this view
     */
    private void setupChildren() {
        username = (TextView) findViewById(R.id.nr_username);
        userTitle = (TextView) findViewById(R.id.nr_userTitle);
        userPosts = (TextView) findViewById(R.id.nr_userPosts);
        userJoin = (TextView) findViewById(R.id.nr_userJoin);
        postDate = (TextView) findViewById(R.id.nr_postDate);
        likeText = (TextView) findViewById(R.id.nr_likeText);
        postBox = (TextView) findViewById(R.id.postBox);

        reportbutton = (ImageView) findViewById(R.id.nr_reportbutton);
        linkbutton = (ImageView) findViewById(R.id.nr_linkbutton);
        avatar = (ImageView) findViewById(R.id.nr_image);
        downButton = (ImageView) findViewById(R.id.nr_downButton);
        quoteButton = (ImageView) findViewById(R.id.nr_quoteButton);
        editButton = (ImageView) findViewById(R.id.nr_editButton);
        pmButton = (ImageView) findViewById(R.id.nr_pmButton);
        deleteButton = (ImageView) findViewById(R.id.nr_deleteButton);

        postText = (WebView) findViewById(R.id.nr_postText);
    }

    /**
     * Inflate the view, this technically only gets called the first time the
     * view is accessed
     * @param parent    The parent of the view
     * @return          An inflated object
     */
    public static PostView inflate(ViewGroup parent) {
        PostView itemView = (PostView)LayoutInflater.from(parent.getContext())
                .inflate(R.layout.view_newreply, parent, false);
        return itemView;
    }

    /**
     * Setup our view here.  After the view has been inflated and all of the
     * view objects have been initialized, we can inflate our view here
     * @param post      The model we are going to use to populate the view
     * @param position  Get the position of this view on the window
     * @param listener  The listener object to attach to the view
     */
    public void setPost(final PostModel post, final int position, final OnClickListener listener) {
        username.setText(post.getUserName());
        userTitle.setText(post.getUserTitle());
        userPosts.setText(post.getUserPostCount());
        userJoin.setText(post.getJoinDate());
        postDate.setText(post.getPostDate());
        reportbutton.setVisibility(View.VISIBLE);

        if(PreferenceHelper.isShowLikes(getContext())) {
            if(post.getLikes().size() > 0) {
                String delim = "", likes = "Liked by: ";
                for(String like : post.getLikes()) {
                    likes += delim + like;
                    delim = ", ";
                }
                likeText.setText(likes);
            } else {
                likeText.setVisibility(View.GONE);
            }
        } else {
            likeText.setVisibility(View.GONE);
        }

        // Lets make sure we remove any font formatting that was done within
        // the text
        String trimmedPost = 
                post.getUserPost().replaceAll("(?i)<(/*)font(.*?)>", "");

        // Show attachments if the preference allows it
        if(PreferenceHelper.isShowAttachments(getContext())) 
            trimmedPost = appendAttachments(trimmedPost, post.getAttachments());

        // Show signatures if the preference allows it
        if(PreferenceHelper.isShowSignatures(getContext()) && post.getUserSignature() != null)
            trimmedPost = appendSignature(trimmedPost, post.getUserSignature());

        // Set html Font color
        trimmedPost = Utils.postFormatter(trimmedPost, getContext());
        postText.setBackgroundColor(Color.DKGRAY);
        postText.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        postText.getSettings().setAppCachePath(
                Cache.getExternalCacheDir(getContext()).getAbsolutePath());
        postText.getSettings().setAllowFileAccess(false);
        postText.getSettings().setAppCacheEnabled(true);
        postText.getSettings().setJavaScriptEnabled(false);
        postText.getSettings().setSupportZoom(false);
        postText.getSettings().setSupportMultipleWindows(false);
        postText.getSettings().setUserAgentString(WebUrls.USER_AGENT);
        postText.getSettings().setDatabaseEnabled(false);
        postText.getSettings().setDomStorageEnabled(false);
        postText.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
        postText.setOnTouchListener(new View.OnTouchListener() {
            @SuppressLint("ClickableViewAccessibility")
            public boolean onTouch(View v, MotionEvent event) {
                return (event.getAction() == MotionEvent.ACTION_MOVE);
            }
        });
        postText.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // Check if the URL for the site, and if it is a thread or a category
                Log.d(TAG, "User Clicked Embedded url");
                boolean isThread = false;
                if(url.contains("rx8club.com")) {
                    isThread = url.matches(".*\\-\\d+\\/$");
                    Log.d(TAG, String.format("The Link (%s) is %sa thread", url, (isThread)? "" : "NOT "));

                    Bundle args = new Bundle();
                    args.putString("link", url);

                    if(isThread) {
                        FragmentUtils.fragmentTransaction(
                                (FragmentActivity)view.getContext(), 
                                ThreadFragment.newInstance(), 
                                false, true, args);
                        return true;
                    }
                }

                // Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
                Intent intent = 
                        new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                MainApplication.getAppContext().startActivity(intent);
                return true;
            }
        });

        postText.loadDataWithBaseURL(WebUrls.rootUrl, trimmedPost, "text/html", "utf-8", ""); 

        // Load up the avatar of hte user, but remember to remove
        // the dateline at the end of the file so that we aren't
        // creating multiple images for a user.  The image still
        // gets returned without a date
        if(PreferenceHelper.isShowAvatars(getContext())) {
            String nodate_avatar = 
                    post.getUserImageUrl().indexOf('?') == -1? 
                            post.getUserImageUrl() : 
                                post.getUserImageUrl().substring(0, post.getUserImageUrl().indexOf('?'));

            if(!nodate_avatar.isEmpty()) {  
                imageLoader.DisplayImage(nodate_avatar, avatar);
            } else {
                avatar.setImageResource(R.drawable.rotor_icon);
            }
        }

        // Display the right items if the user is logged in
        setUserIcons(this, post.isLoggedInUser());      

        downButton
            .setOnClickListener(listener);

        // Set click listeners if we are logged in, hide the buttons
        // if we are not logged in
        if(LoginFactory.getInstance().isGuestMode()) {
            quoteButton.setVisibility(View.GONE);
            editButton.setVisibility(View.GONE);
            pmButton.setVisibility(View.GONE);
            deleteButton.setVisibility(View.GONE);
            reportbutton.setVisibility(View.GONE);
        } else {
            quoteButton
                .setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    Log.d(TAG, "Quote Clicked");
                    String txt = Html.fromHtml(post.getUserPost()).toString();
                    String finalText = String.format("[quote=%s]%s[/quote]",
                            post.getUserName(), txt);
                    postBox.setText(finalText);
                    postBox.requestFocus();
                }
            });

            editButton
                .setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    Log.d(TAG, "Edit Clicked");

                    // Create new fragment and transaction
                    Bundle args = new Bundle();
                    args.putString("postid", post.getPostId());
                    args.putString("securitytoken", post.getToken());
                    Fragment newFragment = new EditPostFragment();

                    FragmentUtils.fragmentTransaction((FragmentActivity)getContext(), 
                            newFragment, true, true, args);
                }
            });

            reportbutton
                .setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View arg0) {
                        Log.d(TAG, "Report Clicked");
                        new ReportPostDialog(getContext(), 
                                post.getToken(), post.getPostId()).show();  
                    }
                });

            linkbutton
                .setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View arg0) {
                        Log.d(TAG, "Link Clicked");
                        ClipboardManager clipboard = 
                                (android.content.ClipboardManager) 
                                getContext().getSystemService(Context.CLIPBOARD_SERVICE); 
                        android.content.ClipData clip = 
                                android.content.ClipData.newPlainText("thread link", post.getRootThreadUrl());
                        clipboard.setPrimaryClip(clip);
                        Toast.makeText(getContext(), 
                                "Thread Link Copied To Clipboard", 
                                Toast.LENGTH_LONG).show();
                    }
                });

            pmButton
                .setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    Log.d(TAG, "PM Clicked");

                    // Create new fragment and transaction
                    Bundle args = new Bundle();
                    args.putString("user", post.getUserName());
                    Fragment newFragment = new NewPrivateMessageFragment();
                    FragmentUtils.fragmentTransaction((FragmentActivity)getContext(), 
                            newFragment, false, true, args);
                }
            });

            final boolean isFirstPost = (position == 0);
            deleteButton
                .setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {            
                    DialogInterface.OnClickListener dialogClickListener = 
                        new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            switch (which){
                            case DialogInterface.BUTTON_POSITIVE:  
                                // Create new fragment and transaction
                                Bundle args = new Bundle();
                                args.putString("postid", post.getPostId());
                                args.putString("securitytoken", post.getToken());
                                args.putBoolean("delete", true);
                                args.putBoolean("deleteThread", isFirstPost && post.isLoggedInUser());
                                Fragment newFragment = new EditPostFragment();
                                FragmentUtils.fragmentTransaction((FragmentActivity)getContext(), 
                                        newFragment, false, true, args);
                                break;
                            }
                        }
                    };

                    AlertDialog.Builder builder = 
                            new AlertDialog.Builder(getContext());
                    builder
                        .setMessage("Are you sure you want to delete your post?")
                        .setPositiveButton("Yes", dialogClickListener)
                        .setNegativeButton("No", dialogClickListener)
                        .show();
                }
            });
        }
    }

    /**
     * Append the signature to the end of the user's post
     * @param trimmedPost   The user's post
     * @param signature     The signature to add
     * @return              A full user post
     */
    private String appendSignature(String trimmedPost, String signature) {
        return String.format("%s<br><br>%s", trimmedPost, signature);
    }

    /**
     * Append attachments to the end of this post if they exist
     * @param trimmedPost   The current post
     * @param attachments   The attachments of the post
     * @return              An appended html string
     */
    private String appendAttachments(String trimmedPost,
            List<String> attachments) {
        if(attachments == null || attachments.isEmpty())
            return trimmedPost;

        // Create an html string for the attachments
        String attachString = "";
        for(String attachment : attachments)
            attachString += 
            String.format("<a href=\"%s\"><img class=\"attachment\" src=\"%s\"></a>&nbsp;", 
                    attachment, attachment);

        // Now append to the original text
        trimmedPost = 
                String.format("%s<br><br><b>Attachments:</b><br>%s", 
                        trimmedPost, attachString);

        return trimmedPost;
    }

    /**
     * If the post is by the logged in user, make sure that they can see the edit and 
     * delete buttons
     * @param vi                The thread view object
     * @param isLoggedInUser    True if post is by logged user
     */
    private void setUserIcons(View vi, boolean isLoggedInUser) {
        quoteButton
        .setVisibility(View.VISIBLE);

        pmButton
        .setVisibility(View.VISIBLE);

        editButton
        .setVisibility(isLoggedInUser? View.VISIBLE : View.GONE);

        deleteButton
        .setVisibility(isLoggedInUser? View.VISIBLE : View.GONE);
    }
}

项目的视图布局:

 <?xml version="1.0" encoding="utf-8"?>
 <merge
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="wrap_content" >
<!--  ListRow Left sied Thumbnail image -->
<LinearLayout
    android:id="@+id/thumbnail"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_marginRight="5dip"
    android:baselineAligned="false"
    android:padding="0dip" >

    <ImageView
        android:id="@+id/tv_image"
        android:layout_width="16dip"
        android:layout_height="16dip"
        android:adjustViewBounds="false"
        android:baselineAlignBottom="false"
        android:cropToPadding="false"
        android:scaleType="fitXY"
        android:src="@drawable/push_pin" />

</LinearLayout>

<!-- Title Of Thread-->

<TextView
    android:id="@+id/tv_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@+id/thumbnail"
    android:layout_marginRight="60dp"
    android:layout_toRightOf="@+id/thumbnail"
    android:text="@string/tvTitle"
    android:textColor="#040404"
    android:textSize="12dip"
    android:textStyle="bold"
    android:typeface="sans" />

<!-- Started By -->

<TextView
    android:id="@+id/tv_postUser_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tv_title"
    android:layout_marginTop="1dip"
    android:layout_toRightOf="@+id/thumbnail"
    android:text="@string/tvStarted"
    android:textColor="#000000"
    android:textSize="10dip" />

<TextView
    android:id="@+id/tv_postUser"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tv_title"
    android:textColor="#ffffff"
    android:textSize="10dip"
    android:layout_marginTop="1dip"
    android:layout_toRightOf="@+id/tv_postUser_label"
    android:text="The Thread Starter" />


<!-- Started By -->
<TextView
    android:id="@+id/tv_lastUser_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tv_postUser_label"
    android:textColor="#000000"
    android:textSize="10dip"
    android:layout_marginTop="1dip"
    android:layout_toRightOf="@+id/thumbnail"
    android:text="@string/tvLastPost" />

<TextView
    android:id="@+id/tv_lastUser"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tv_postUser"
    android:textColor="#ffffff"
    android:textSize="10dip"
    android:layout_marginTop="1dip"
    android:layout_marginLeft="5dp"
    android:layout_toRightOf="@+id/tv_lastUser_label"
    android:text="@string/tvLastPostPerson" />

<TextView
    android:id="@+id/tv_lastUserDate"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tv_postUser"
    android:textColor="#ffffff"
    android:textSize="10dip"
    android:layout_marginTop="1dip"
    android:layout_marginLeft="5dp"
    android:layout_toRightOf="@+id/tv_lastUser"
    android:text="01/01/2014" />



<!-- Rightend Post Counts -->
<RelativeLayout 
    android:id="@+id/postcount_details"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignBottom="@id/tv_lastUser">


<LinearLayout 
    android:id="@+id/tv_labels"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="left">
    <TextView
        android:id="@+id/tv_postCount_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="@string/tvTotalPosts"
        android:layout_marginRight="5dip"
        android:textSize="10dip"
        android:textColor="#000000"
        android:textStyle="bold"/>
    <TextView
        android:id="@+id/tv_viewCount_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="@string/tvTotalViews"
        android:layout_marginRight="5dip"
        android:textSize="10dip"
        android:textColor="#000000"
        android:textStyle="bold"/>
    <TextView
        android:id="@+id/tv_myCount_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="@string/tvMyPosts"
        android:layout_marginRight="5dip"
        android:textSize="10dip"
        android:textColor="#000000"
        android:textStyle="bold"/>
</LinearLayout>
<LinearLayout 
    android:id="@+id/tv_label_values"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/tv_labels"
    android:orientation="vertical"
    android:gravity="right">
   <TextView
        android:id="@+id/tv_postCount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="5:45"
        android:layout_marginRight="5dip"
        android:textSize="10dip"
        android:textColor="#ffffff"
        android:textStyle="bold"/>          

    <TextView
        android:id="@+id/tv_viewCount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="5:45"
        android:layout_marginRight="5dip"
        android:textSize="10dip"
        android:textColor="#ffffff"
        android:textStyle="bold"/>      

    <TextView
        android:id="@+id/tv_myCount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="5:45"
        android:layout_marginRight="5dip"
        android:textSize="10dip"
        android:textColor="#ffffff"
        android:textStyle="bold"/>
</LinearLayout>

</RelativeLayout>

<ImageView
    android:id="@+id/tv_attachment"
    android:layout_width="15dip"
    android:layout_height="15dip"
    android:layout_alignBottom="@id/tv_lastUser_label"
    android:layout_marginRight="10dp"
    android:layout_toLeftOf="@id/postcount_details"
    android:src="@drawable/paperclip" />

<LinearLayout 
    android:id="@+id/tv_forum_details"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tv_lastUserDate"
    android:orientation="horizontal"
    android:layout_alignLeft="@id/tv_lastUser_label"
    android:visibility="gone">
    <TextView
        android:id="@+id/tv_forum_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"            
        android:textColor="#000000"
        android:textSize="10dip"
        android:layout_marginTop="1dip"
        android:text="@string/tvForum"/>

    <TextView
        android:id="@+id/tv_forum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dip"
        android:ellipsize="end"
        android:text=""
        android:textColor="#000000"
        android:textSize="10dip" />
</LinearLayout>
</merge>

应用背景:这只是我经常访问的论坛的移动界面。它基本上使用JSoup来解析html,然后将该内容加载到Android用户的友好视图中。

问题描述:线程中的每个帖子都存储为一个名为“PostView”的视图。这些视图是通过ThreadFragment创建的,它负责读取线程的内容并使用数组适配器来存储和回收这些视图。

我遇到的问题是每一行自然都有自己的高度。这会导致在滚动时“闪烁”的视图,因为“PostView”的WebView的内容被创建/回收。理想情况下,我需要一种方法来第一次保存WebView的高度,这样当它需要回收视图时,它可以在加载内容时强制该高度。

1 个答案:

答案 0 :(得分:0)

好吧,一种方法是通过ListAdapter传递TextView的高度以及数据。创建一个TextView,其中包含“已消失”的可见性以及layoutHeight:

之类的想法
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"
    android:id="@+id/layoutHeight" />

使用传递的高度加载TextView。

然后,覆盖ListView的{​​{1}}方法并从那里设置高度。

getView()

如果有任何帮助,以下是SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] { "receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath}) { @Override public View getView (int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); TextView layoutHeightTextView = (TextView) view.findViewById(R.id.layoutHeight); //get the value from layoutHeight and set the height of this view to that... return view; } }; 覆盖的示例:Create a ListView with selectable rows/change background color of ListView rows when clicked

这不是一个完美的方法。差远了。我仍然不确定为什么你的ListView会闪烁,因为getView()应该没有闪烁就可以了。