具有列表视图的活动存在一个问题,即列表视图在每个单元格中具有不同数量的内容。当用户向下滚动时,列表视图是平滑的,并且按预期工作。 但是,当用户向上滚动时,将重新加载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 :
在
ArrayListGetterSetter test = new ArrayListGetterSetter();
Log.e("test.getSize()", ""+test.getSize());
LazyObjectDrawingAdapter
中的始终返回0.因此,查询元素会导致空指针异常。 如何获取身高值?
答案 0 :(得分:0)
在getItemId中你应该返回位置而不是零。
@Override
public long getItemId(int position) {
return 0;
}
它应该是:
@Override
public long getItemId(int position) {
return position;
}
我认为这可能会有所帮助。