gpt4 book ai didi

java - 获取 ListView 单元格的高度以方便向上滚动

转载 作者:太空宇宙 更新时间:2023-11-04 14:14:22 27 4
gpt4 key购买 nike

具有 ListView 的 Activity 存在一个问题,即 ListView 的每个单元格中的内容量不同。当用户向下滚动时, ListView 很流畅并且一切按预期工作。 但是,当用户向上滚动时, ListView 的缓存数据将被重新加载。这次重绘使 ListView 向上滚动变得跳跃。我发现,如果我在向下滚动时计算每个单元格的高度并将其保存在 ArrayList 中,并在用户向上滚动可见列表项时应用相同的高度,则可以修复跳跃滚动。我通过为每个帖子设置静态高度进行了相同的测试,滚动条没有跳动。 但是,我必须根据每个单元格高度使其动态。 ListView 代码可能看起来有点复杂!

Activity :

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;
}

}

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;
}

}

TestDrawableClass:

Click to see the code

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

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

最佳答案

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

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

应该是:

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

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

关于java - 获取 ListView 单元格的高度以方便向上滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27937509/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com