Android GridView 重复项解析 SDK
Android GridView duplicates items Parse SDK
我正在调用查询以使用 Parse SDK 在我的 android 应用程序中获取一些对象,一切正常,除了 GridView,它在向下滚动后复制第一个项目以获取后面的对象第二个甚至没有从第二个项目中获得正确的图像,如下所示:
这是我的代码:
public class Home extends AppCompatActivity {
/* Variables */
List<ParseObject> eventsArray = null;
Cursor cursor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// Set Title on the ActionBar
getSupportActionBar().setTitle("Events");
// Call query
queryEvents();
}
// MARK: - QUERY EVENTS
public void queryEvents() {
ParseQuery<ParseObject> query = ParseQuery.getQuery(Configs.EVENTS_CLASS_NAME);
query.whereEqualTo(Configs.EVENTS_IS_PENDING, false);
query.orderByDescending(Configs.EVENTS_END_DATE);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> objects, ParseException error) {
if (error == null) {
eventsArray = objects;
// CUSTOM GRID ADAPTER
class GridAdapter extends BaseAdapter {
private Cursor cursor;
private Context context;
public GridAdapter(Context context, List<ParseObject> objects, Cursor cursor) {
super();
this.context = context;
if (cursor != null) {
cursor.moveToFirst();
this.cursor = cursor;
}
}
// CONFIGURE CELL
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
// Inflate event_cell.xml
gridView = inflater.inflate(R.layout.event_cell, null);
// Get Parse object
ParseObject eventObj = eventsArray.get(position);
// Get Title
TextView titleTxt = (TextView) gridView.findViewById(R.id.titleTxt);
titleTxt.setText(eventObj.getString(Configs.EVENTS_TITLE).toString().toUpperCase());
// Get Address
TextView addTxt = (TextView) gridView.findViewById(R.id.addressTxt);
addTxt.setText(eventObj.getString(Configs.EVENTS_LOCATION).toString());
// Get Start & End dates
TextView dateTxt = (TextView) gridView.findViewById(R.id.dateTxt);
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy | hh:mm a");
dateTxt.setText(dateFormat.format(startDate).toUpperCase() + " - " + dateFormat.format(endDate).toUpperCase());
// Get Image
ParseFile fileObject = (ParseFile)eventObj.get(Configs.EVENTS_IMAGE);
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException error) {
if (error == null) {
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
if (bmp != null) {
ImageView eventImage = (ImageView) findViewById(R.id.eventImage);
eventImage.setImageBitmap(bmp);
}
}}});
} else { gridView = convertView; }
return gridView;
}
@Override
public int getCount() { return eventsArray.size(); }
@Override
public Object getItem(int position) { return eventsArray.get(position); }
@Override
public long getItemId(int position) { return position; }
}
// Init GridView and set its adapter
GridView eventsGrid = (GridView) findViewById(R.id.eventsGridView);
eventsGrid.setAdapter(new GridAdapter(Home.this, eventsArray, cursor));
eventsGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ParseObject eventObj = eventsArray.get(position);
Toast.makeText(getApplicationContext(), eventObj.getString(Configs.EVENTS_TITLE), Toast.LENGTH_SHORT).show();
// GO TO EventDetails activity
}
});
// Error in query
} else {
Toast.makeText(getApplicationContext(), error.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}
});
}
光标 是我做错了什么,还是我不需要它?
我应该如何解决此类问题?
谢谢!
你的getView
错了。
如果视图是新视图 convertView == null
,您只需格式化视图(带有标题等...),而不是仅在 convertView == null
时才对其进行膨胀并始终设置它。
另外,不需要 gridView
。
试试这个:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Inflate event_cell.xml
convertView= inflater.inflate(R.layout.event_cell, null);
}
// Get Parse object
ParseObject eventObj = eventsArray.get(position);
// Get Title
TextView titleTxt = (TextView) convertView.findViewById(R.id.titleTxt);
titleTxt.setText(eventObj.getString(Configs.EVENTS_TITLE).toString().toUpperCase());
// Get Address
TextView addTxt = (TextView) convertView.findViewById(R.id.addressTxt);
addTxt.setText(eventObj.getString(Configs.EVENTS_LOCATION).toString());
// Get Start & End dates
TextView dateTxt = (TextView) convertView.findViewById(R.id.dateTxt);
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy | hh:mm a");
dateTxt.setText(dateFormat.format(startDate).toUpperCase() + " - " + dateFormat.format(endDate).toUpperCase());
final ImageView eventImage = (ImageView) convertView.findViewById(R.id.eventImage);
// Get Image
ParseFile fileObject = (ParseFile)eventObj.get(Configs.EVENTS_IMAGE);
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException error) {
if (error == null) {
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
if (bmp != null) {
eventImage.setImageBitmap(bmp);
}
}}});
return convertView;
}
顺便说一句,你应该把getView分成方法,比如setViewTitle
、setViewImage
...
它很难读懂,而且对于您或其他可能从事此代码工作的人来说,维护它也很困难。
我正在调用查询以使用 Parse SDK 在我的 android 应用程序中获取一些对象,一切正常,除了 GridView,它在向下滚动后复制第一个项目以获取后面的对象第二个甚至没有从第二个项目中获得正确的图像,如下所示:
这是我的代码:
public class Home extends AppCompatActivity {
/* Variables */
List<ParseObject> eventsArray = null;
Cursor cursor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// Set Title on the ActionBar
getSupportActionBar().setTitle("Events");
// Call query
queryEvents();
}
// MARK: - QUERY EVENTS
public void queryEvents() {
ParseQuery<ParseObject> query = ParseQuery.getQuery(Configs.EVENTS_CLASS_NAME);
query.whereEqualTo(Configs.EVENTS_IS_PENDING, false);
query.orderByDescending(Configs.EVENTS_END_DATE);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> objects, ParseException error) {
if (error == null) {
eventsArray = objects;
// CUSTOM GRID ADAPTER
class GridAdapter extends BaseAdapter {
private Cursor cursor;
private Context context;
public GridAdapter(Context context, List<ParseObject> objects, Cursor cursor) {
super();
this.context = context;
if (cursor != null) {
cursor.moveToFirst();
this.cursor = cursor;
}
}
// CONFIGURE CELL
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
// Inflate event_cell.xml
gridView = inflater.inflate(R.layout.event_cell, null);
// Get Parse object
ParseObject eventObj = eventsArray.get(position);
// Get Title
TextView titleTxt = (TextView) gridView.findViewById(R.id.titleTxt);
titleTxt.setText(eventObj.getString(Configs.EVENTS_TITLE).toString().toUpperCase());
// Get Address
TextView addTxt = (TextView) gridView.findViewById(R.id.addressTxt);
addTxt.setText(eventObj.getString(Configs.EVENTS_LOCATION).toString());
// Get Start & End dates
TextView dateTxt = (TextView) gridView.findViewById(R.id.dateTxt);
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy | hh:mm a");
dateTxt.setText(dateFormat.format(startDate).toUpperCase() + " - " + dateFormat.format(endDate).toUpperCase());
// Get Image
ParseFile fileObject = (ParseFile)eventObj.get(Configs.EVENTS_IMAGE);
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException error) {
if (error == null) {
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
if (bmp != null) {
ImageView eventImage = (ImageView) findViewById(R.id.eventImage);
eventImage.setImageBitmap(bmp);
}
}}});
} else { gridView = convertView; }
return gridView;
}
@Override
public int getCount() { return eventsArray.size(); }
@Override
public Object getItem(int position) { return eventsArray.get(position); }
@Override
public long getItemId(int position) { return position; }
}
// Init GridView and set its adapter
GridView eventsGrid = (GridView) findViewById(R.id.eventsGridView);
eventsGrid.setAdapter(new GridAdapter(Home.this, eventsArray, cursor));
eventsGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ParseObject eventObj = eventsArray.get(position);
Toast.makeText(getApplicationContext(), eventObj.getString(Configs.EVENTS_TITLE), Toast.LENGTH_SHORT).show();
// GO TO EventDetails activity
}
});
// Error in query
} else {
Toast.makeText(getApplicationContext(), error.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}
});
}
光标 是我做错了什么,还是我不需要它? 我应该如何解决此类问题?
谢谢!
你的getView
错了。
如果视图是新视图 convertView == null
,您只需格式化视图(带有标题等...),而不是仅在 convertView == null
时才对其进行膨胀并始终设置它。
另外,不需要 gridView
。
试试这个:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Inflate event_cell.xml
convertView= inflater.inflate(R.layout.event_cell, null);
}
// Get Parse object
ParseObject eventObj = eventsArray.get(position);
// Get Title
TextView titleTxt = (TextView) convertView.findViewById(R.id.titleTxt);
titleTxt.setText(eventObj.getString(Configs.EVENTS_TITLE).toString().toUpperCase());
// Get Address
TextView addTxt = (TextView) convertView.findViewById(R.id.addressTxt);
addTxt.setText(eventObj.getString(Configs.EVENTS_LOCATION).toString());
// Get Start & End dates
TextView dateTxt = (TextView) convertView.findViewById(R.id.dateTxt);
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy | hh:mm a");
dateTxt.setText(dateFormat.format(startDate).toUpperCase() + " - " + dateFormat.format(endDate).toUpperCase());
final ImageView eventImage = (ImageView) convertView.findViewById(R.id.eventImage);
// Get Image
ParseFile fileObject = (ParseFile)eventObj.get(Configs.EVENTS_IMAGE);
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException error) {
if (error == null) {
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
if (bmp != null) {
eventImage.setImageBitmap(bmp);
}
}}});
return convertView;
}
顺便说一句,你应该把getView分成方法,比如setViewTitle
、setViewImage
...
它很难读懂,而且对于您或其他可能从事此代码工作的人来说,维护它也很困难。