获取listview单元格的高度以便于向上滚动

时间:2015-01-14 07:07:58

标签: java android listview

具有列表视图的活动存在一个问题,即列表视图在每个单元格中具有不同数量的内容。当用户向下滚动时,列表视图是平滑的,并且按预期工作。 但是,当用户向上滚动时,将重新加载listview的缓存数据。这次重绘让listview向上滚动。我想通过的是,如果我在向下滚动时计算每个单元格的高度并将其保存在ArrayList中并在用户向上滚动到可见列表项时应用相同的高度,则可以修复跳转滚动。我通过为每个帖子设置静态高度来测试相同的内容,滚动条没有跳动。 但是,我必须根据每个单元格高度使其动态。列表视图代码可能看起来有点复杂!

活动

public class PostListActivity extends Activity implements OnScrollListener {
    TableLayout html_output_table;
    int id = 0;
    List<String> dataFromParse = new ArrayList<String>();
    LazyObjectDrawingAdapter adapter;
    ListView listView;
    List<RichPost> richPostArrayList = new ArrayList<RichPost>();

    private int currentScrollState;
    private int currentVisibleItemCount;
    private int skipParam = 0;
    private boolean flag_loading = false;

    int mLastFirstVisibleItem = 0;

    HashMap<integer, String> hashMap = new HashMap<integer, String>();

    int initialHeight = 0;
    ArrayList<Integer> heightList = new ArrayList<Integer>();

    int position;

    boolean scrolling = false;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_post_list_list);

        listView = (ListView) findViewById(R.id.listView);
        // Need to create the adapter constructor
        listView.setOnScrollListener(this);
        adapter = new LazyObjectDrawingAdapter(PostListActivity.this, dataFromParse, richPostArrayList);
        listView.setAdapter(adapter);

        setContent();
        // cityListBody("Hello");

    }

    public void setContent(){

        // Pull data from Parse
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("userid", ParseUser.getCurrentUser().getObjectId());
        params.put("skip", skipParam);

        ParseCloud.callFunctionInBackground("studentsPosts", params, new FunctionCallback<List<List<ParseObject>>>() {
            @Override
            public void done(List<List<ParseObject>> data, com.parse.ParseException arg1){
                if (data == null) {

                } else {
                    Log.e("size ", "RUNNING Size :   " + data.size());

                    if (data.size() > 0) {
                        flag_loading = false;
                        for (int i = 0; i < data.size(); i++) {
                            RichPost rc = new RichPost();
                            //if (heightList.size()>i){
                                Log.e("heightList.size()", ""+heightList.size());
                            //}
                            if (data.get(0).get(0).get("htmlContent") != null) {
                                // Switch i to 1 to force just 1 additon.
                                dataFromParse.add(data.get(i).get(0).getString("htmlContent"));
                                rc.setHtmlCode(data.get(i).get(0).getString("htmlContent"));
                                Log.i("Calling notifiyDataSetchanged", "now");
                            }
                            if (data.get(i).get(0).get("photos") != null) {

                                List<ParseFile> pFileList;
                                pFileList = (List<ParseFile>) data.get(i).get(0).get("photos");

                                rc.setPhotosArray(pFileList);

                            }
                            if (data.get(i).get(0).getParseFile("photo") != null) {
                                // Time to retrieve the photo
                                ParseFile getParseFile;
                                getParseFile = (ParseFile) data.get(i).get(0).get("photo");
                                rc.setPhoto(getParseFile);
                            }

                            richPostArrayList.add(rc);
                            adapter.notifyDataSetChanged();
                        }
                    }
                }

            }

        });

    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState){
        this.currentScrollState = scrollState;
        this.isScrollCompleted();
    }

    private void isScrollCompleted(){
        if (this.currentVisibleItemCount >= 5 && this.currentScrollState == SCROLL_STATE_IDLE) {

        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount){
        this.currentVisibleItemCount = visibleItemCount;

        if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount != 0) {
            if (flag_loading == false) {
                flag_loading = true;
                Log.d("IN ON SCROLL", "NOW: " + skipParam);
                skipParam = skipParam + 10;
                setContent();
            }

        }


        // to determine scroll up or down
        if (mLastFirstVisibleItem < firstVisibleItem) {
            Log.i("SCROLLING DOWN", "TRUE");
//          View c = listView.getChildAt(0);
//          int scrolly = -c.getTop() + listView.getFirstVisiblePosition() * c.getHeight();
//          Log.e("scrolly", "" + scrolly);
            int scrolly = getItemHeightofListView(listView, firstVisibleItem);
            Log.e("scrolly down", "" + scrolly);
            //setting the cell height from total height - initial height
            heightList.add(scrolly-initialHeight);
            ArrayListGetterSetter test = new ArrayListGetterSetter();
            test.setList(scrolly-initialHeight);
            initialHeight = scrolly;
            //hashMap.put(firstVisibleItem, "" + scrolly);
            //Log.e("Item show",""+heightList.get(firstVisibleItem));
            scrolling = true;
        }
        if (mLastFirstVisibleItem > firstVisibleItem) {
            Log.i("SCROLLING UP", "TRUE");

//          View c = listView.getChildAt(0);
//          int scrolly = -c.getTop() + listView.getFirstVisiblePosition() * c.getHeight();
//          Log.e("scrolly", "" + scrolly);
//          int scrolly = getItemHeightofListView(listView, firstVisibleItem);
//          Log.e("scrolly up", "" + scrolly);
            if (firstVisibleItem <= heightList.size()) {
            //getting the heights from the arraylist while scrolling up 
            //Log.e("Item show",""+heightList.get(firstVisibleItem));

            position = firstVisibleItem;
            }
        }
        mLastFirstVisibleItem = firstVisibleItem;

    }

    public static int getItemHeightofListView(ListView listView, int items) {

        ListAdapter mAdapter = listView.getAdapter();

        int listviewElementsheight = 0;
        // for listview total item height
        // items = mAdapter.getCount(); 


        for (int i = 0; i < items; i++) {

            View childView = mAdapter.getView(i, null, listView);
            childView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            listviewElementsheight+= childView.getMeasuredHeight();
            }


            return listviewElementsheight;

        }


} 

适配器

public class LazyObjectDrawingAdapter extends BaseAdapter {
    PostListActivity postList = new PostListActivity();
    RichPost rc = new RichPost();

    Context mContext;
    List<String> randomItems = new ArrayList<String>();
    List<RichPost> richPostArrayList = new ArrayList<RichPost>();
    private LayoutInflater inflater = null;
    ArrayList<Integer> heightList = new ArrayList<Integer>();

    public LazyObjectDrawingAdapter(Context context, List<String> contentComingIn, List<RichPost> richPostArrayList) {
        this.mContext = context;
        this.inflater = LayoutInflater.from(mContext);
        this.randomItems = contentComingIn;
        this.richPostArrayList = richPostArrayList;

    }
//  public LazyObjectDrawingAdapter(Context context, List<String> contentComingIn, List<RichPost> richPostArrayList, ArrayList<Integer> heightList) {
//      this.mContext = context;
//      this.inflater = LayoutInflater.from(mContext);
//      this.randomItems = contentComingIn;
//      this.richPostArrayList = richPostArrayList;
//      this.heightList = heightList;
//
//  }

    @Override
    public int getCount() {
        //return 1;
        //Log.i("GetCount size : ", " " + randomItems.size());
        //return 1;
        return randomItems.size();
    }

    @Override
    public Object getItem(int position) {
        return randomItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        View vi = convertView;

        if (convertView == null) {
            vi = inflater.inflate(R.layout.lazy_adapter, null);
            holder = new ViewHolder();
            setIds(vi, holder);
            vi.setTag(holder);
        } else {
            holder = (ViewHolder) vi.getTag();
        }

        ArrayListGetterSetter test = new ArrayListGetterSetter();
        Log.e("test.getSize()", ""+test.getSize());
        //test.getListValues(position);
        tryingNewClass(holder, vi, mContext, (String) randomItems.get(position), richPostArrayList.get(position));

        return vi;
    }

    private void step1(String fromActivity) {
        Log.d("Html output", "" + fromActivity);
    }

    private void step2(String html){
        Document doc = Jsoup.parse(html);
        Element element = doc.body();
        Elements elements = element.select("img");
        Log.w("Size of the elements ", " " + elements.size());
        for(Element e : elements){
            Log.d("step 2: ", "img: " + e.toString());
        }
    }

    private void step2PicksUpWorks(String html){
        Document doc = Jsoup.parse(html);
        Elements imgs = doc.body().select("p");
        for (Element e : imgs){
            if(!e.toString().contentEquals("")){
                Log.i("Img sources ", ": " + e.ownText());
            }
        }
    }

    private void tryingNewClass(ViewHolder holder, View view, Context context, String source, RichPost richPost){
            //setting static height for testing, feel free to remove it anytime 
            int heightValue = 500;
            holder.textToDraw.setMinHeight(heightValue + 200);

        TestDrawableClass tdc = new TestDrawableClass(source, holder.textToDraw, context, holder.imageToDraw, richPost);
    }

    private void URLCombinedTest(int position, ViewHolder holder, View view, Context context, String source){

        ImageView iv = new ImageView(context);
        TextView tv = new TextView(context);
        URLCombined uip = new URLCombined(position, iv, context, tv);
        Spanned spanned = Html.fromHtml(source, uip, null);
        tv.setText(spanned);
        //holder.linearLayoutForImages.addView(iv);
        holder.linearLayoutForImages.addView(tv);

    }

    /*
     *  Time to do the on draw 
     */

    private void lineByLine(int position, ViewHolder holder, View view, Context context, String source){
        //Need to get line by line and then run it via the test parsers and add it to the layout dynmically via the ViewGrou parpent
        Document doc = Jsoup.parse(source);
        Element element = doc.body();



        Elements ele = element.select("img");
        for (int i = 0; i < ele.size(); i++) {
/*          Log.w("For loop ", " " + i + " "+  ele.get(i).html());
            Log.d("For loop ", " " + i + " "+  ele.get(i).text());
            Log.i("For loop ", " " + i + " "+  ele.get(i));*/
            addURLImageParser(position, holder, view, context, ""+ele.get(i));
        }

        Elements all = doc.select("b");
        for (int i = 0; i < all.size(); i++) {
            Log.i("For loop ", " " + i + " "+  all.get(i));
            addURLTextParser(position, holder, view, context, ""+all.get(i));
        }

        Log.w("About to start a loop to check everything ", "now");
        int imgValue = 0;
        for (Element el:doc.select("body").select("*")) {
            imgValue++;
              // loop over all textnodes of these children
            Log.i("Element siblings ", " " + el.nextElementSibling() + " "  +imgValue);
            Element tempElement = el.nextElementSibling();
            if(el.nextElementSibling() == null){
                Log.w("Element is null", "value is : " + el + " " + imgValue);
            }

            if(el.nextElementSibling() != null){
                //Loop through the siblings.
                if(el.nextElementSibling().hasText()){
                    //Log.d("Can we check any text after the fact ? ", " " + el);
                    //Log.e("Element has text: ", " " + el.nextElementSibling());
                }

                if(el.nextElementSibling().hasText() == false){
                    Elements elements = tempElement.select("img");
                    if(elements.isEmpty() == false){
                        //Log.e("Element text is false ", " " + elements);
                    }
                }
            }

        imgValue = 0;
        }
    }



    private void addURLTextParser(int position, ViewHolder holder, View view, Context context, String source){
        Log.w("in add text url", "now");
        TextView tv = new TextView(context);

        URLTextParser utp = new URLTextParser(tv, context, 0);
        Spanned spanned = Html.fromHtml(source, utp, null);
        tv.setText(spanned);

        holder.linearLayoutForImages.addView(tv);
        //Now attach it the layout
    }

    private void addURLImageParser(int position, ViewHolder holder, View view, Context context, String source){
        //Log.w("in add image url", "now");
        ImageView iv = new ImageView(context);
        URLImageParser uip = new URLImageParser(position, iv, context);
        Spanned spanned = Html.fromHtml(source, uip, null);

        holder.linearLayoutForImages.setId(position);
        holder.linearLayoutForImages.addView(iv);

    }

    private void testURLTextParser(int position, ViewHolder holder, View view, Context context, String source){
        //Lets just get text only
        Document doc = Jsoup.parse(source);
        Elements img = doc.body().select("p");
        for (int i = 0; i < img.size(); i++) {

            //Log.w("Checking null ", " " + img.get(i).text().contentEquals(""));
            if( img.get(i).text().contentEquals("") == false){
                Log.i("output : ", " " + img.get(i).text());
                Log.d("Output2 ", " " + img.get(i).html());

                URLTextParser utp = new URLTextParser(holder.textToDraw, context, 0);
                Spanned spanned = Html.fromHtml(img.get(i).html(), utp, null);
                holder.textToDraw.setText(spanned);

            }

        }

    }

    private void testURLImageParser(int position, ViewHolder holder, View view, Context context, String source){
            //Log.d("In step 3 ", " Position :  " + position);



            //Lets do some crazy work right now. So lets start with just images. Make them 3 seperate ImageViews to draw
                //Pos 0 has three images, but lets cycle throgh the mfirst
                Document doc = Jsoup.parse(source);
                Elements img = doc.body().select("img");
                //Now we have all possible image 'source links'

                for (int i = 0; i < img.size(); i++) {
                    //Lets loop through them one by one
                    Log.w("checking the output of the img ", "" + img.get(i).toString());
                    ImageView iv = new ImageView(context); //Create a holder for the images
                    URLImageParser uip = new URLImageParser(position, iv, context); 
                    Spanned spanned = Html.fromHtml(img.get(i).toString(), uip, null);
                    holder.linearLayoutForImages.addView(iv);
            }


    }


    private void setIds(View vi, ViewHolder holder) {
        holder.textToDraw = (TextView) vi.findViewById(R.id.textOnly);
        holder.imageToDraw = (ImageView) vi.findViewById(R.id.imageOnly);
        holder.linearLayoutForImages = (LinearLayout) vi.findViewById(R.id.linearForImages);
    }

    static class ViewHolder {
        TextView textToDraw;
        ImageView imageToDraw;
        Object objectCouldBeAnything;
        Canvas toTry;
        LinearLayout linearLayoutForImages;
    }

}

Class ArrayListGetterSetter

public class ArrayListGetterSetter {

    ArrayList<Integer> heightList = new ArrayList<Integer>();
    int valueFromList;
    int size;

    public int getListValues(int itemIndex) {

        valueFromList = heightList.get(itemIndex);
        return valueFromList;
    }

    public void setList(int value) {
        heightList.add(value);
    }

    public int getSize(){
        size = heightList.size();
        return size;
    }

}

Class TestDrawableClass

Click to see the code

 ArrayListGetterSetter test = new ArrayListGetterSetter();
        Log.e("test.getSize()", ""+test.getSize());
LazyObjectDrawingAdapter中的

始终返回0.因此,查询元素会导致空指针异常。 如何获取身高值?

1 个答案:

答案 0 :(得分:0)

在getItemId中你应该返回位置而不是零。

@Override
    public long getItemId(int position) {
        return 0;
    }

它应该是:

@Override
    public long getItemId(int position) {
        return position;
    }

我认为这可能会有所帮助。