使用自定义适配器和方向接收 ListView 程序的空指针异常?
Receiving nullpointer exception for ListView program using custom adapter and orientation?
我正在制作一个应用程序,其中 ArrayList
在纵向和横向方向上由两个 ListViews
表示。为此,我一直在使用一个自定义适配器来扩充我的 listView。但是每当我为 landscape ListView
实例化自定义适配器时,我都会收到 NullPointer Exception
。有什么建议么?
抛出异常的行:
listLand.setAdapter(customAdapter);
主要活动
public class MainActivity extends AppCompatActivity {
ListView listPort;
ListView listLand;
ArrayList<Flick> flicks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listLand = findViewById(R.id.listLand);
listPort = findViewById(R.id.listPort);
flicks = new ArrayList<>();
flicks.add(new Flick("Wizard of Oz", "Metro-Goldwyn-Mayer", "VARIOUS","1939", "", 98));
flicks.add(new Flick("Star Wars", "LucasFilm", "George Lucas", "1977","",93));
flicks.add(new Flick("Psycho","Paramount", "Alfred Hitchcock", "1960", "", 97));
flicks.add(new Flick("King Kong", "RKO Pictures", "Merian C. Cooper & Ernest B. Schoedsack", "1933", "", 98));
flicks.add(new Flick("2001: A Space Odyssey", "Metro-Goldwyn-Mayer", "Stanley Kubrick", "1968", "", 93));
flicks.add(new Flick("Citizen Kane", "RKO Pictures", "Orson Welles", "1941", "", 100));
flicks.add(new Flick("Snow White and the Seven Dwarfs", "Walt Disney Pictures", "VARIOUS", "1937", "",98));
flicks.add(new Flick("Casablanca", "Warner Bros.", "Michael Curtiz", "1942", "", 97));
flicks.add(new Flick("The Godfather", "Paramount", "Francis Ford Coppola", "1972", "", 98));
flicks.add(new Flick("Jaws", "Universal", "Steven Spielberg", "1975", "", 97));
CustomAdapter customAdapter = new CustomAdapter(this, R.layout.custom_layout, flicks);
listPort.setAdapter(customAdapter);
listLand.setAdapter(customAdapter);
}
public class CustomAdapter extends ArrayAdapter<Flick>
{
Context context;
int resource;
List<Flick> list;
public CustomAdapter(@NonNull Context context, int resource, @NonNull List<Flick> objects) {
super(context, resource, objects);
this.context=context;
this.resource=resource;
list=objects;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
LayoutInflater layoutInflater=(LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View adapterView=layoutInflater.inflate(resource,null);
TextView title = adapterView.findViewById(R.id.title);
ImageView imageView=adapterView.findViewById(R.id.imageView);
Button up=adapterView.findViewById(R.id.upButton);
Button down=adapterView.findViewById(R.id.downButton);
title.setText(list.get(position).getTitle());
switch(list.get(position).getStudio())
{
case "Warner Bros.":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "Paramount":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "Universal":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "LucasFilm":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "RKO Pictures":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "Walt Disney Pictures":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "Metro-Goldwyn-Mayer":
imageView.setImageResource(R.drawable.warnerbros);
break;
}
return adapterView;
}
}
}
猜测:您有两种不同的布局 - 一种用于纵向,一种用于横向。根据设备方向,只有其中一个将通过 findViewById
加载。请记住,当您旋转设备时,将重新创建 activity(并调用 onCreate
)。在设置适配器之前,您应该检查 listPort
和 listLand
是否有 null
。您没有同时使用两者。
像这样:
if (listPort != null) {
listPort.setAdapter(customAdapter); // Portrait mode
} else {
listLand.setAdapter(customAdapter); // Landscape mode
}
其中一个应该是非空的,前提是其他一切正常。
如果正如我猜测的那样,您有一个 values/activity_main.xml
和一个 values-land/activity_main.xml
,您可以通过在两个地方使用相同的列表 ID 来让自己的生活更轻松。例如,
public class MainActivity extends AppCompatActivity {
ListView list;
ArrayList<Flick> flicks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = findViewById(R.id.list);
flicks = new ArrayList<>();
flicks.add(new Flick("Wizard of Oz", "Metro-Goldwyn-Mayer", "VARIOUS","1939", "", 98));
...
flicks.add(new Flick("Jaws", "Universal", "Steven Spielberg", "1975", "", 97));
CustomAdapter customAdapter = new CustomAdapter(this, R.layout.custom_layout, flicks);
listt.setAdapter(customAdapter);
}
...
}
我正在制作一个应用程序,其中 ArrayList
在纵向和横向方向上由两个 ListViews
表示。为此,我一直在使用一个自定义适配器来扩充我的 listView。但是每当我为 landscape ListView
实例化自定义适配器时,我都会收到 NullPointer Exception
。有什么建议么?
抛出异常的行:
listLand.setAdapter(customAdapter);
主要活动
public class MainActivity extends AppCompatActivity {
ListView listPort;
ListView listLand;
ArrayList<Flick> flicks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listLand = findViewById(R.id.listLand);
listPort = findViewById(R.id.listPort);
flicks = new ArrayList<>();
flicks.add(new Flick("Wizard of Oz", "Metro-Goldwyn-Mayer", "VARIOUS","1939", "", 98));
flicks.add(new Flick("Star Wars", "LucasFilm", "George Lucas", "1977","",93));
flicks.add(new Flick("Psycho","Paramount", "Alfred Hitchcock", "1960", "", 97));
flicks.add(new Flick("King Kong", "RKO Pictures", "Merian C. Cooper & Ernest B. Schoedsack", "1933", "", 98));
flicks.add(new Flick("2001: A Space Odyssey", "Metro-Goldwyn-Mayer", "Stanley Kubrick", "1968", "", 93));
flicks.add(new Flick("Citizen Kane", "RKO Pictures", "Orson Welles", "1941", "", 100));
flicks.add(new Flick("Snow White and the Seven Dwarfs", "Walt Disney Pictures", "VARIOUS", "1937", "",98));
flicks.add(new Flick("Casablanca", "Warner Bros.", "Michael Curtiz", "1942", "", 97));
flicks.add(new Flick("The Godfather", "Paramount", "Francis Ford Coppola", "1972", "", 98));
flicks.add(new Flick("Jaws", "Universal", "Steven Spielberg", "1975", "", 97));
CustomAdapter customAdapter = new CustomAdapter(this, R.layout.custom_layout, flicks);
listPort.setAdapter(customAdapter);
listLand.setAdapter(customAdapter);
}
public class CustomAdapter extends ArrayAdapter<Flick>
{
Context context;
int resource;
List<Flick> list;
public CustomAdapter(@NonNull Context context, int resource, @NonNull List<Flick> objects) {
super(context, resource, objects);
this.context=context;
this.resource=resource;
list=objects;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
LayoutInflater layoutInflater=(LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View adapterView=layoutInflater.inflate(resource,null);
TextView title = adapterView.findViewById(R.id.title);
ImageView imageView=adapterView.findViewById(R.id.imageView);
Button up=adapterView.findViewById(R.id.upButton);
Button down=adapterView.findViewById(R.id.downButton);
title.setText(list.get(position).getTitle());
switch(list.get(position).getStudio())
{
case "Warner Bros.":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "Paramount":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "Universal":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "LucasFilm":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "RKO Pictures":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "Walt Disney Pictures":
imageView.setImageResource(R.drawable.warnerbros);
break;
case "Metro-Goldwyn-Mayer":
imageView.setImageResource(R.drawable.warnerbros);
break;
}
return adapterView;
}
}
}
猜测:您有两种不同的布局 - 一种用于纵向,一种用于横向。根据设备方向,只有其中一个将通过 findViewById
加载。请记住,当您旋转设备时,将重新创建 activity(并调用 onCreate
)。在设置适配器之前,您应该检查 listPort
和 listLand
是否有 null
。您没有同时使用两者。
像这样:
if (listPort != null) {
listPort.setAdapter(customAdapter); // Portrait mode
} else {
listLand.setAdapter(customAdapter); // Landscape mode
}
其中一个应该是非空的,前提是其他一切正常。
如果正如我猜测的那样,您有一个 values/activity_main.xml
和一个 values-land/activity_main.xml
,您可以通过在两个地方使用相同的列表 ID 来让自己的生活更轻松。例如,
public class MainActivity extends AppCompatActivity {
ListView list;
ArrayList<Flick> flicks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = findViewById(R.id.list);
flicks = new ArrayList<>();
flicks.add(new Flick("Wizard of Oz", "Metro-Goldwyn-Mayer", "VARIOUS","1939", "", 98));
...
flicks.add(new Flick("Jaws", "Universal", "Steven Spielberg", "1975", "", 97));
CustomAdapter customAdapter = new CustomAdapter(this, R.layout.custom_layout, flicks);
listt.setAdapter(customAdapter);
}
...
}