Я пытаюсь настроить gridLayout в представлении рециркулятора, используя несколько XML-макетов grid_cell, каждая из которых содержит 5 ImageViews. У меня был recyclerView, работающий нормально, пока я не реструктурировал код для размещения базы данных.
Проблема заключается в том, что все ImageViews инициализируются как нулевые в конструкторе MapViewHolder, что приводит к java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)
для ссылки на нулевой объект"
public class MapFragment extends Fragment
{
private GameDataStorage gameDataStorage;
private RecyclerView rv;
private MapAdapter adapter;
private GridLayoutManager gridLayoutManager;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
gameDataStorage = ((SubApplication)getActivity().getApplication()).gameDataStorage;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle bundle)
{
//Inflate the view from fragment_map.xml layout.
View view = inflater.inflate(R.layout.fragment_map, parent, false);
//Crate the recycler view from the map_recycler_view.xml layout
rv = view.findViewById(R.id.map_recycler_view);
adapter = new MapAdapter();
//Initialise the grid layout manager
gridLayoutManager = new GridLayoutManager(getActivity(), GameData.getInstance().getSettings().getMapHeight(), GridLayoutManager.HORIZONTAL, false);
//Set the recycler view adapter
rv.setAdapter(adapter);
//Set the layout manager to be a horizontal scrolling grid
rv.setLayoutManager(gridLayoutManager);
return view;
}
public class MapViewHolder extends RecyclerView.ViewHolder
{
private ImageView structure;
private ImageView topLeft;
private ImageView topRight;
private ImageView bottomLeft;
private ImageView bottomRight;
public MapViewHolder(LayoutInflater li, ViewGroup parent)
{
super(li.inflate(R.layout.grid_cell, parent, false));
int size = parent.getMeasuredHeight() / GameData.getInstance().getSettings().getMapHeight() + 1;
ViewGroup.LayoutParams lp = parent.getLayoutParams();
lp.height = size;
lp.width = size;
structure = (ImageView) parent.findViewById(R.id.structure);
topLeft = (ImageView) parent.findViewById(R.id.top_left);
topRight = (ImageView) parent.findViewById(R.id.top_right);
bottomLeft = (ImageView) parent.findViewById(R.id.bottom_left);
bottomRight = (ImageView) parent.findViewById(R.id.bottom_right);
//DEBUGGING
Log.d("GAME_DATA", "structure reference is initialised as " + structure);
Log.d("GAME_DATA", "topLeft reference is initialised as " + topLeft);
Log.d("GAME_DATA", "topRight reference is initialised as " + topRight);
Log.d("GAME_DATA", "bottomLeft reference is initialised as " + bottomLeft);
Log.d("GAME_DATA", "bottomRight reference is initialised as " + bottomRight);
}
public void bind(final MapElement element, final int index)
{
if(element.getStructure() != null){
structure.setImageResource(element.getStructure().getImageId());
}
else
{
if(structure == null)
{
Log.d("GAME_DATA", "structure reference is null for mapElement " + index);
}
structure.setImageResource(GameData.getInstance().getEmpty());
}
topLeft.setImageResource(element.getTopLeft());
topRight.setImageResource(element.getTopRight());
bottomLeft.setImageResource(element.getBottomLeft());
bottomRight.setImageResource(element.getBottomRight());
structure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
int row = index % GameData.getInstance().getSettings().getMapHeight();
int col = index / GameData.getInstance().getSettings().getMapHeight();
StructureData.setStructureAt(row, col);
gameDataStorage.updateMapElement(element, element.getStructure(), index);
adapter.notifyItemChanged(index);
}
});
structure.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return false;
}
});
}
}
// END_INCLUDE(recyclerViewSampleViewHolder)
public class MapAdapter extends RecyclerView.Adapter<MapViewHolder>
{
// BEGIN_INCLUDE(recyclerViewOnCreateViewHolder)
// Create new views (invoked by the layout manager)
@Override
public MapViewHolder onCreateViewHolder(ViewGroup container, int viewType)
{
Log.d("GAME_DATA", "new MapViewHolder using ViewGroup " + container + " and viewType " + viewType);
return new MapViewHolder(LayoutInflater.from(getActivity()), container);
}
// END_INCLUDE(recyclerViewOnCreateViewHolder)
// BEGIN_INCLUDE(recyclerViewOnBindViewHolder)
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(MapViewHolder vh, int index) {
// Get element from your dataset at this position and replace the contents of the view
// with that element
int row = index % GameData.getInstance().getSettings().getMapHeight();
int col = index / GameData.getInstance().getSettings().getMapHeight();
MapElement element = GameData.getInstance().getMapLoc(row, col);
vh.bind(element, index);
}
// END_INCLUDE(recyclerViewOnBindViewHolder)
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
int rows = GameData.getInstance().getMap().length;
int cols = GameData.getInstance().getMap()[0].length;
int length = rows * cols;
Log.d("GAME_DATA", "getItemCount returns: " + length);
return length;
}
}
}
Logcat Вывод:
10-22 19: 31: 59.177 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: новый MapViewHolder с использованием ViewGroup androidx.recyclerview.widget.RecyclerView {353fb6f6 VFED .... ...... ID 0,0-1080,1188 # 7f07005e app: id / map_recycler_view} и viewType 0 10-22 19: 31: 59.187 19926-19926 / com. example.mad_assignment_rebuild D / GAME_DATA: ссылка на структуру инициализируется как ноль 10-22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: ссылка topLeft инициализируется как ноль 10-22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: ссылка topRight инициализируется как ноль 10-22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: bСсылка ottomLeft инициализируется как ноль 10-22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: ссылка bottomRight инициализируется как ноль 10-22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuildD / GAME_DATA: ссылка на структуру является нулевой для mapElement 0
Вывод ошибки отладки:
E / AndroidRuntime: FATAL EXCEPTION: main Процесс: com.example.mad_assignment_rebuild, PID: 19926 java.lang.NullPointerException: попытка вызвать виртуальный метод void android.widget.ImageView.setImageResource (int) для нулевой ссылки на объект в com.example.mad_assignment_rebuild.MapRecyclerFiles.MapFragment $ MapViewHolder.bind (MapF:101) в com.example.mad_assignment_rebuild.MapRecyclerFiles.MapFragment $ MapAdapter.onBindViewHolder (MapFragment.java:154) в com.example.mad_assignment_rebuild.MapRecyclerFiles.MapFragment $ MapAdapter.onava_rag * 1016F1