Custom BaseAdapter 上的第一项未显示在 Gridview 上,Gridview 上的 ClickListener 不起作用
First item on Custom BaseAdapter doesn't show up at Gridview and ClickListener on Gridview doesn't work
我坐了两天就是为了搜索我的fragment的gridview和adapter的代码有什么问题。第一项没有显示在我的网格视图中。
这是我的片段代码
public class FragmentConsumerHomeCanteen extends Fragment {
private final String TAG = "ConsumerHomeCanteen";
private GridView fchCanGrid;
private ArrayList<CanteenRecordDetails> canteenRecordDetailsArrayList;
private CanteenAdapter canteenAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_consumer_home_canteen, container, false);
resourceVariables(view);
canteenRecordDetailsArrayList = new ArrayList<>();
canteenRecordDetailsArrayList.clear();
CafeTreydDatabase cafeTreydDatabase = new CafeTreydDatabase(getActivity());
Cursor cursor = cafeTreydDatabase.getCanteenForConsumerHomeCanteen(TAG);
if (cursor.moveToFirst()) {
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
String name = cursor.getString(1);
String open = cursor.getString(2);
String close = cursor.getString(3);
byte[] image = cursor.getBlob(4);
canteenRecordDetailsArrayList.add(new CanteenRecordDetails(id, name, open, close, image));
canteenAdapter = new CanteenAdapter(getActivity(), canteenRecordDetailsArrayList);
canteenAdapter.notifyDataSetChanged();
}
fchCanGrid.setAdapter(canteenAdapter);
Log.i(TAG, "Setting adapter to GridView Successful");
} else {
Log.i(TAG, "Cursor returns null");
}
return view;
}
private void resourceVariables(View view) {
fchCanGrid = view.findViewById(R.id.fchCanGrid);
Log.i(TAG, "Resourcing Successful");
}
private static class CanteenRecordDetails {
private int id;
private String name;
private String open;
private String close;
private byte[] image;
private CanteenRecordDetails(int id, String name, String open, String close, byte[] image) {
this.id = id;
this.name = name;
this.open = open;
this.close = close;
this.image = image;
}
private int getId() {
return id;
}
private String getName() {
return name;
}
private String getOpen() {
return open;
}
private String getClose() {
return close;
}
private byte[] getImage() {
return image;
}
}
private static class CanteenAdapter extends BaseAdapter{
private final Context context;
private final ArrayList<CanteenRecordDetails> canteenRecordDetailsArrayList;
private final LayoutInflater layoutInflater;
private CanteenAdapter(Context context, ArrayList<CanteenRecordDetails> canteenRecordDetailsArrayList) {
this.context = context;
this.canteenRecordDetailsArrayList = canteenRecordDetailsArrayList;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return canteenRecordDetailsArrayList.size();
}
@Override
public Object getItem(int position) {
return canteenRecordDetailsArrayList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.layout_fragment_consumer_home_canteen, parent, false);
}
LinearLayout lfchcLL = convertView.findViewById(R.id.lfchCanLL);
TextView lfchCanName = convertView.findViewById(R.id.lfchCanName);
TextView lfchCanOpen = convertView.findViewById(R.id.lfchCanOpen);
TextView lfchCanClose = convertView.findViewById(R.id.lfchCanClose);
ImageView lfchCanImage = convertView.findViewById(R.id.lfchCanImage);
CanteenRecordDetails canteenRecordDetails = canteenRecordDetailsArrayList.get(position);
lfchCanName.setText(canteenRecordDetails.getName());
lfchCanOpen.setText(String.format("OPEN: %s", canteenRecordDetails.getOpen()));
lfchCanClose.setText(String.format("CLOSE: %s", canteenRecordDetails.getClose()));
byte[] tempImage = canteenRecordDetails.getImage();
Bitmap bitmap = BitmapFactory.decodeByteArray(tempImage, 0, tempImage.length);
lfchCanImage.setImageBitmap(bitmap);
lfchcLL.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, lfchCanName.getText(), Toast.LENGTH_SHORT).show();
String TAG = "ConsumerHomeCanteen";
try {
((ActivityConsumerHome)context).setCanteenId(canteenRecordDetails.getId());
((ActivityConsumerHome)context).setCanteenName(canteenRecordDetails.getName());
Navigation.findNavController(parent).navigate(R.id.action_fragmentConsumerHomeCanteen_to_fragmentConsumerHomeCategory);
Log.i(TAG, "Navigating to next Fragment");
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "Failed to set canteenId");
}
}
});
return convertView;
}
}
}
如果您注意到了,我将布局的 onclickListener
放置在适配器中的 getView
内,因为我无法在 GridView
上使用 onItemClickListener
。它不工作。无论我在互联网上看到什么解决方案,它都不起作用。
gridview
仍然会跳过适配器上的第一项。我使用信息日志来确保数据库和 arraylist
工作正常。它工作正常。只是griview
我觉得有问题
问题: 使用 cursor.moveToFirst()
光标移动到第一项,然后在捕获第一个 item/row 之前调用 cursor.moveToNext()
在下面的 while
块中。这让您在有机会将第一个添加到适配器之前转到第二个 item/row。
if (cursor.moveToFirst()) {
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
String name = cursor.getString(1);
String open = cursor.getString(2);
String close = cursor.getString(3);
byte[] image = cursor.getBlob(4);
canteenRecordDetailsArrayList.add(new CanteenRecordDetails(id, name, open, close, image));
canteenAdapter = new CanteenAdapter(getActivity(), canteenRecordDetailsArrayList);
canteenAdapter.notifyDataSetChanged();
}
fchCanGrid.setAdapter(canteenAdapter);
Log.i(TAG, "Setting adapter to GridView Successful");
} else {
Log.i(TAG, "Cursor returns null");
}
解法:
调用cursor.moveToNext()
前需要执行while
块内的代码
使用do/while
而不是while
以便迭代代码在检查while
条件
之前运行
if (cursor.moveToFirst()) {
do {
int id = cursor.getInt(0);
String name = cursor.getString(1);
String open = cursor.getString(2);
String close = cursor.getString(3);
byte[] image = cursor.getBlob(4);
canteenRecordDetailsArrayList.add(new CanteenRecordDetails(id, name, open, close, image));
canteenAdapter = new CanteenAdapter(getActivity(), canteenRecordDetailsArrayList);
canteenAdapter.notifyDataSetChanged();
} while (cursor.moveToNext());
fchCanGrid.setAdapter(canteenAdapter);
Log.i(TAG, "Setting adapter to GridView Successful");
} else {
Log.i(TAG, "Cursor returns null");
}
我坐了两天就是为了搜索我的fragment的gridview和adapter的代码有什么问题。第一项没有显示在我的网格视图中。
这是我的片段代码
public class FragmentConsumerHomeCanteen extends Fragment {
private final String TAG = "ConsumerHomeCanteen";
private GridView fchCanGrid;
private ArrayList<CanteenRecordDetails> canteenRecordDetailsArrayList;
private CanteenAdapter canteenAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_consumer_home_canteen, container, false);
resourceVariables(view);
canteenRecordDetailsArrayList = new ArrayList<>();
canteenRecordDetailsArrayList.clear();
CafeTreydDatabase cafeTreydDatabase = new CafeTreydDatabase(getActivity());
Cursor cursor = cafeTreydDatabase.getCanteenForConsumerHomeCanteen(TAG);
if (cursor.moveToFirst()) {
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
String name = cursor.getString(1);
String open = cursor.getString(2);
String close = cursor.getString(3);
byte[] image = cursor.getBlob(4);
canteenRecordDetailsArrayList.add(new CanteenRecordDetails(id, name, open, close, image));
canteenAdapter = new CanteenAdapter(getActivity(), canteenRecordDetailsArrayList);
canteenAdapter.notifyDataSetChanged();
}
fchCanGrid.setAdapter(canteenAdapter);
Log.i(TAG, "Setting adapter to GridView Successful");
} else {
Log.i(TAG, "Cursor returns null");
}
return view;
}
private void resourceVariables(View view) {
fchCanGrid = view.findViewById(R.id.fchCanGrid);
Log.i(TAG, "Resourcing Successful");
}
private static class CanteenRecordDetails {
private int id;
private String name;
private String open;
private String close;
private byte[] image;
private CanteenRecordDetails(int id, String name, String open, String close, byte[] image) {
this.id = id;
this.name = name;
this.open = open;
this.close = close;
this.image = image;
}
private int getId() {
return id;
}
private String getName() {
return name;
}
private String getOpen() {
return open;
}
private String getClose() {
return close;
}
private byte[] getImage() {
return image;
}
}
private static class CanteenAdapter extends BaseAdapter{
private final Context context;
private final ArrayList<CanteenRecordDetails> canteenRecordDetailsArrayList;
private final LayoutInflater layoutInflater;
private CanteenAdapter(Context context, ArrayList<CanteenRecordDetails> canteenRecordDetailsArrayList) {
this.context = context;
this.canteenRecordDetailsArrayList = canteenRecordDetailsArrayList;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return canteenRecordDetailsArrayList.size();
}
@Override
public Object getItem(int position) {
return canteenRecordDetailsArrayList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.layout_fragment_consumer_home_canteen, parent, false);
}
LinearLayout lfchcLL = convertView.findViewById(R.id.lfchCanLL);
TextView lfchCanName = convertView.findViewById(R.id.lfchCanName);
TextView lfchCanOpen = convertView.findViewById(R.id.lfchCanOpen);
TextView lfchCanClose = convertView.findViewById(R.id.lfchCanClose);
ImageView lfchCanImage = convertView.findViewById(R.id.lfchCanImage);
CanteenRecordDetails canteenRecordDetails = canteenRecordDetailsArrayList.get(position);
lfchCanName.setText(canteenRecordDetails.getName());
lfchCanOpen.setText(String.format("OPEN: %s", canteenRecordDetails.getOpen()));
lfchCanClose.setText(String.format("CLOSE: %s", canteenRecordDetails.getClose()));
byte[] tempImage = canteenRecordDetails.getImage();
Bitmap bitmap = BitmapFactory.decodeByteArray(tempImage, 0, tempImage.length);
lfchCanImage.setImageBitmap(bitmap);
lfchcLL.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, lfchCanName.getText(), Toast.LENGTH_SHORT).show();
String TAG = "ConsumerHomeCanteen";
try {
((ActivityConsumerHome)context).setCanteenId(canteenRecordDetails.getId());
((ActivityConsumerHome)context).setCanteenName(canteenRecordDetails.getName());
Navigation.findNavController(parent).navigate(R.id.action_fragmentConsumerHomeCanteen_to_fragmentConsumerHomeCategory);
Log.i(TAG, "Navigating to next Fragment");
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "Failed to set canteenId");
}
}
});
return convertView;
}
}
}
如果您注意到了,我将布局的 onclickListener
放置在适配器中的 getView
内,因为我无法在 GridView
上使用 onItemClickListener
。它不工作。无论我在互联网上看到什么解决方案,它都不起作用。
gridview
仍然会跳过适配器上的第一项。我使用信息日志来确保数据库和 arraylist
工作正常。它工作正常。只是griview
我觉得有问题
问题: 使用 cursor.moveToFirst()
光标移动到第一项,然后在捕获第一个 item/row 之前调用 cursor.moveToNext()
在下面的 while
块中。这让您在有机会将第一个添加到适配器之前转到第二个 item/row。
if (cursor.moveToFirst()) {
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
String name = cursor.getString(1);
String open = cursor.getString(2);
String close = cursor.getString(3);
byte[] image = cursor.getBlob(4);
canteenRecordDetailsArrayList.add(new CanteenRecordDetails(id, name, open, close, image));
canteenAdapter = new CanteenAdapter(getActivity(), canteenRecordDetailsArrayList);
canteenAdapter.notifyDataSetChanged();
}
fchCanGrid.setAdapter(canteenAdapter);
Log.i(TAG, "Setting adapter to GridView Successful");
} else {
Log.i(TAG, "Cursor returns null");
}
解法:
调用cursor.moveToNext()
while
块内的代码
使用do/while
而不是while
以便迭代代码在检查while
条件
if (cursor.moveToFirst()) {
do {
int id = cursor.getInt(0);
String name = cursor.getString(1);
String open = cursor.getString(2);
String close = cursor.getString(3);
byte[] image = cursor.getBlob(4);
canteenRecordDetailsArrayList.add(new CanteenRecordDetails(id, name, open, close, image));
canteenAdapter = new CanteenAdapter(getActivity(), canteenRecordDetailsArrayList);
canteenAdapter.notifyDataSetChanged();
} while (cursor.moveToNext());
fchCanGrid.setAdapter(canteenAdapter);
Log.i(TAG, "Setting adapter to GridView Successful");
} else {
Log.i(TAG, "Cursor returns null");
}