gpt4 book ai didi

java - 调用notifyDataSetChanged 时,具有customAdapter 的ListView 未更新?

转载 作者:行者123 更新时间:2023-12-01 11:02:02 24 4
gpt4 key购买 nike

我有一个带有两个适配器的 ListView 。他们收到一个包含一些数据的数组,当滚动到 ListView 底部时,更多数据被加载到数组中,这里 ListView 应该添加新数据。

问题:如何使 ListView 反射(reflect)新数据以及为什么当我调用 adAdapter.notifyDataSetChanged(); 时它没有更新?

fragment 内部类,我在 onPostExecute 中下载数据并更新 UI:

@Override
protected void onPostExecute(String result) {

super.onPostExecute(result);

numberofpagesshown = numberofpagesshown + 1;

if(numberofpagesshown == 1 ) {

list = (ListView) getActivity().findViewById(R.id.search_listview_movie);

adapter = new SearchListViewAdapter(getActivity(), mylist);

adAdapter = new BannerAdListView2(getActivity(), adapter);

// list.setAdapter(adapter); this works when adapter.notifyDataSetChanged(); also is in the else statement but here I don't use the BannerAdListView2 adapter which i want to?

list.setAdapter(adAdapter);

bar.setVisibility(View.GONE);
}
else {

// adapter.notifyDataSetChanged(); // Here the listview should get refresh with the new data

adAdapter.notifyDataSetChanged();

bar.setVisibility(View.GONE);

}


// Attach the listener to the AdapterView onCreate
list.setOnScrollListener(new EndlessScrollListener() {
@Override
public void onLoadMore(int page, int totalItemsCount) {
// Triggered only when new data needs to be appended to the list
// Append new items to AdapterView
if(pageNumberInt < totalPagesInt){

++incre;
new DownloadJSON().execute();
}

}
});


}

这是我的 SearchListViewAdapter:

public class SearchListViewAdapter extends BaseAdapter{

Context context;
ArrayList<HashMap<String, String>> data;
HashMap<String, String> mylist = new HashMap<>();


static String url;
static String title;

public SearchListViewAdapter(Context a, ArrayList<HashMap<String, String>> d) {
context = a;
data = d;
}

public int getCount() {
return data.size();
}

public HashMap<String, String> getItem(int position) {
return data.get(position);
}

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

public View getView(final int position, View convertView, ViewGroup parent) {

// Avoid unneccessary calls to findViewById() on each row
final ViewHolder holder;

/*
* If convertView is not null, reuse it directly, no inflation
* Only inflate a new View when the convertView is null.
*/

if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.search_list_item, parent, false);

holder = new ViewHolder();

holder.poster = (ImageView) convertView.findViewById(R.id.list_image);

holder.textForTitle = (TextView) convertView.findViewById(R.id.search_title);

holder.textForTitle.setTag(position);

convertView.setTag(holder);
}
else{

// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
holder.textForTitle.setTag(data.get(position));
}



mylist = data.get(position);


final String mediaType = mylist.get("media_type");

if (mediaType.equals("movie")) {

String posterPath = mylist.get("poster_path");
url = "http://image.tmdb.org/t/p/w185" + posterPath;
title = mylist.get("title");
} else if (mediaType.equals("tv")) {

String posterPath = mylist.get("poster_path");
url = "http://image.tmdb.org/t/p/w185" + posterPath;
title = mylist.get("original_name");
} else {

String posterPath = mylist.get("profile_path");
url = "http://image.tmdb.org/t/p/w185" + posterPath;
title = mylist.get("name");

}


// set image url correctly
// sizes for image 45, 92, 154, 185, 300, 500


// load image url into poster
Picasso.with(context).load(url).into(holder.poster);

// set title to textview

holder.textForTitle.setText(title);





return convertView;


}



class ViewHolder {
ImageView poster;
TextView textForTitle;
}

}

还有我的 BannerAdListView2 适配器:

public class BannerAdListView2 extends BaseAdapter
{

Activity activity;
Context context;
BaseAdapter delegate;
int k = 7;
int baseItems;
int noAds;



// Constructor takes in a BaseAdapter
public BannerAdListView2(Activity activity, BaseAdapter delegate ) {

this.activity = activity;
this.delegate = delegate;

baseItems = delegate.getCount();
noAds = baseItems / k;
LayoutInflater mLayoutInflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}


@Override
public int getCount() {
// Total count includes list items and ads.
return baseItems + noAds;
}

@Override
public Object getItem(int position) {
// Return null if an item is an ad. Otherwise return the delegate item.
if (isItemAnAd(position)) {
return null;
}
return delegate.getItem(getOffsetPosition(position));
}

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

@Override
public int getViewTypeCount() {
return delegate.getViewTypeCount() + noAds;
}

@Override
public int getItemViewType(int position) {
if (isItemAnAd(position)) {
return delegate.getViewTypeCount();
} else {
return delegate.getItemViewType(getOffsetPosition(position));
}
}

@Override
public boolean areAllItemsEnabled() {
return false;
}

@Override
public boolean isEnabled(int position) {
return (!isItemAnAd(position)) && delegate.isEnabled(getOffsetPosition(position));
}

private boolean isItemAnAd(int position) {


if (position < k) return false;
// Calculate current offset caused by ads already embedded

if (position==k){
return true;
}
else {
return isItemAnAd(position-k);
}


}

// Get the position that is offset by the insertion of the ads
private int getOffsetPosition(int position) {
int currentNoAds = position / k;
return position - currentNoAds;

}



@Override
public View getView(int position, View convertView, ViewGroup parent) {

// Display every n list items
if (isItemAnAd(position)) {
if (convertView instanceof AdView) {
// Don’t instantiate new AdView, reuse old one
return convertView;
} else {
// Create a new AdView
AdView adView = new AdView(activity);
adView.setAdSize(AdSize.BANNER);
String bannerId = "My unit id";
adView.setAdUnitId(bannerId);

// Disable focus for sub-views of the AdView to avoid problems with
// trackpad navigation of the list.
for (int i = 0; i < adView.getChildCount(); i++)
{
adView.getChildAt(i).setFocusable(false);
}
adView.setFocusable(false);

// Convert the default layout parameters so that they play nice with
// ListView.

float density = activity.getResources().getDisplayMetrics().density;
int height = Math.round(AdSize.BANNER.getHeight() * density);
AbsListView.LayoutParams params = new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT,
height);
adView.setLayoutParams(params);
AdRequest bannerIntermediateReq = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.addTestDevice("d9e108ab") //means that a test ad is shown on my phone
.build();

adView.loadAd(bannerIntermediateReq);

return adView;
}
} else {

// Offload displaying other items to the delegate
return delegate.getView(getOffsetPosition(position) ,
convertView, parent);

}
}
}

编辑:更改了BannerAdListView2的构造函数

 // Constructor takes in a BaseAdapter
public BannerAdListView2(Activity activity, final BaseAdapter delegate ) {

this.activity = activity;
this.delegate = delegate;
delegate.registerDataSetObserver(new DataSetObserver() {
public void onChanged() {
baseItems = delegate.getCount();
noAds = baseItems / k;
}

public void onInvalidated() {
notifyDataSetInvalidated();
}
});
baseItems = delegate.getCount();
noAds = baseItems / k;
LayoutInflater mLayoutInflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

在 fragment 中

@Override
protected void onPostExecute(String result) {

super.onPostExecute(result);

numberofpagesshown = numberofpagesshown + 1;

if(numberofpagesshown == 1 ) {

list = (ListView) getActivity().findViewById(R.id.search_listview_movie);

adapter = new SearchListViewAdapter(getActivity(), mylist);

adAdapter = new BannerAdListView2(getActivity(), adapter);

list.setAdapter(adAdapter);

bar.setVisibility(View.GONE);
}
else {

adapter.notifyDataSetChanged();

bar.setVisibility(View.GONE);

}

}

最佳答案

尝试这个解决方案...DecorerAdapter:

public static abstract class DecorerAdapter extends BaseAdapter {

public int DECORER_ITEM_TYPE;
private final BaseAdapter mInnerAdapter;
private final int mRepeatAfterEvery;
private int mCount;

public DecorerAdapter(BaseAdapter innerAdapter, int repeatAfterEvery) {
mInnerAdapter = innerAdapter;
mRepeatAfterEvery = repeatAfterEvery;
mInnerAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
notifyDataSetChanged();
}

@Override
public void onInvalidated() {
notifyDataSetInvalidated();
}
});
setupAdapter();
}

@Override
public void notifyDataSetChanged() {
setupAdapter();
super.notifyDataSetChanged();
}

private void setupAdapter(){
mCount = mInnerAdapter.getCount();
mCount += (mCount + mRepeatAfterEvery - 2) / (mRepeatAfterEvery - 1);
DECORER_ITEM_TYPE = mInnerAdapter.getViewTypeCount();
}

@Override
public int getCount() {
return mCount;
}

@Override
public Object getItem(int position) {
if(position % mRepeatAfterEvery == 0)
return null;
return mInnerAdapter.getItem(calculateInnerPosition(position));
}

private int calculateInnerPosition(int position) {
return position - (position + mRepeatAfterEvery - 1) / mRepeatAfterEvery;
}

@Override
public long getItemId(int position) {
if(position % mRepeatAfterEvery == 0)
return -1;
return mInnerAdapter.getItemId(calculateInnerPosition(position));
}

@Override
public int getItemViewType(int position) {
if(position % mRepeatAfterEvery == 0)
return DECORER_ITEM_TYPE;
return mInnerAdapter.getItemViewType(calculateInnerPosition(position));
}

@Override
public boolean hasStableIds() {
return mInnerAdapter.hasStableIds();
}

@Override
public int getViewTypeCount() {
return mInnerAdapter.getViewTypeCount() + 1;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(position % mRepeatAfterEvery == 0)
return getDecorerView((position + mRepeatAfterEvery - 1) / mRepeatAfterEvery, convertView, parent);
return mInnerAdapter.getView(calculateInnerPosition( position), convertView, parent);
}

public abstract View getDecorerView(int position, View convertView, ViewGroup parent);
}

代码及用法:

package pl.selvin.decoreradapter;

import android.database.DataSetObserver;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

/*** paste the DecorerAdapter class here ***/

public static class MyListFragment extends ListFragment{
final ArrayList<String> strings = new ArrayList<>();
private BaseAdapter innerAdapter;

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add("Add rnd(10) more");

super.onCreateOptionsMenu(menu, inflater);
}

final Random rnd = new Random();
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final String[] toAdd = new String[rnd.nextInt(10)];
int start = strings.size();
for(int i = 0; i < toAdd.length; i++)
toAdd[i] = (start + i) + "";
Collections.addAll(strings, toAdd);
Toast.makeText(getActivity(), "Added " + toAdd.length + " count: " + strings.size(), Toast.LENGTH_SHORT).show();
innerAdapter.notifyDataSetChanged();
return true;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
for(int i = 0; i < 4; i++) {
strings.add(i + "");
}
innerAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, strings);
setListAdapter(new DecorerAdapter(innerAdapter, 5) {
@Override
public View getDecorerView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = new TextView(getActivity());
convertView.setBackgroundColor(Color.RED);
}
((TextView)convertView).setText("AdView: " + position);
return convertView;
}
});
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
String item = (String)l.getItemAtPosition(position);
Toast.makeText(getActivity(), "Item click: " + (item == null ? "ADVIEW" : item), Toast.LENGTH_LONG).show();
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new MyListFragment(), "LIST").commit();
}
}
}

它在传递给构造函数的每个元素上重复装饰器 View ...

您需要做的就是以与普通适配器中的 getView 类似的方式实现 getDecorerView

how it looks?

关于java - 调用notifyDataSetChanged 时,具有customAdapter 的ListView 未更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33264304/

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