代码之家  ›  专栏  ›  技术社区  ›  VallyMan

Android Studio-自定义ListView崩溃应用程序

  •  1
  • VallyMan  · 技术社区  · 6 年前

    我有一个定制的listview,目的是获取JSON数据并将其显示给用户,但是每当我调用它时,它都会崩溃。

    主班

    public class Main extends AppCompatActivity {
    
    //Change Activity
    //Log Out
    public void OpenBeginningActivity(){
        Intent intent = new Intent(this, Beginning.class);
        startActivity(intent);
    }
    
    //Take Picture
    public void TakePicture(){
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent,0);
    }
    
    //JSON Variables
    final String TAG = Main.class.getSimpleName();
    final String JSONUrl = "http://iameuropeapp.pythonanywhere.com/getcountries";
    private ArrayList<Country> CountryList;
    
    //Variables
    private ProgressDialog ProgressDialog;
    private String UserEmail;
    private FirebaseAuth FirebaseInstance;
    private FirebaseAuth FirebaseAuthentication;
    private FirebaseUser LoggedInUser;
    private TextView UserEmailText;
    private ListView CountryListView;
    private ListAdapter Adapter;
    
    public void ParseJSON(View view){
    
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        //Change Bar Title
        getSupportActionBar().setTitle("Dashboard");
    
        //Get Components
        UserEmailText = (TextView)findViewById(R.id.UserEmail);
        FirebaseInstance = FirebaseAuthentication.getInstance();
        LoggedInUser = FirebaseInstance.getCurrentUser();
    
        //Set Username
        UserEmailText.setText(LoggedInUser.getEmail());
    
        //ListView
        CountryList = new ArrayList<>();
        CountryListView = (ListView) findViewById(R.id.CountryList);
    
        //Countries
        new GetCountries().execute();
    }
    
    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        //Take Photo
        if(item.getItemId() == R.id.MenuItem1){
            TakePicture();
        }
    
        //Sign Out
        else if(item.getItemId() == R.id.MenuItem2){
            FirebaseAuthentication.getInstance().signOut();
            OpenBeginningActivity();
            ProgressDialog.setMessage("Signing out...");
            ProgressDialog.show();
        }
    
        return super.onOptionsItemSelected(item);
    }
    
    private class GetCountries extends AsyncTask<Void, Void, Void> {
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Showing progress dialog
            ProgressDialog = new ProgressDialog(Main.this);
            ProgressDialog.setMessage("Please wait...");
            ProgressDialog.show();
        }
    
        @Override
        protected Void doInBackground(Void... voids) {
            HttpHandler Handler = new HttpHandler();
            String JSONString = Handler.makeServiceCall(JSONUrl);
            Log.e(TAG, "Response:" + JSONString);
    
            if(JSONString != null){
                try {
                    JSONObject CountriesJSONObject = new JSONObject(JSONString);
                    JSONArray Countries = CountriesJSONObject.getJSONArray("countries");
    
                    for (int i = 0; i < Countries.length(); i++) {
                        JSONObject Country = Countries.getJSONObject(i).getJSONObject("country");
                        String CountryID = Country.getString("id");
                        String CountryName = Country.getString("name");
                        String CountryImage = Country.getString("image");
                        CountryList.add(new Country(CountryID, CountryName, CountryImage));
                    }
                } catch (final JSONException e){
                    Log.e(TAG,e.getMessage());
                    ProgressDialog.setMessage("Error loading Data!");
                }
            }
            return null;
        }
    
        @Override
        protected void onPostExecute(Void Result)
        {
            ProgressDialog.dismiss();
            ListAdapter CustomAdapter = new CustomAdapter(Main.this,0,CountryList);
            CountryListView.setAdapter(CustomAdapter);
    
        }
    
    }
    
    }
    

    自定义适配器

    public class CustomAdapter extends ArrayAdapter<Country>{
    
    public ArrayList<Country> ArrayListCountries;
    
    public CustomAdapter(@NonNull Context context,int resource, ArrayList<Country> Countries) {
        super(context, R.layout.activity_main_list, Countries);
    }
    
    @Override
    public View getView(int Position, View view, ViewGroup viewgroup){
        //Init
        LayoutInflater Inflater = LayoutInflater.from(getContext());
        View CustomView = Inflater.inflate(R.layout.activity_main_list, viewgroup, false);
    
        //Get Components
        Country country = ArrayListCountries.get(Position);
        TextView CountryText = (TextView) CustomView.findViewById(R.id.CountryNameText);
        ImageView CountryImage = (ImageView) CustomView.findViewById(R.id.CountryImage);
    
        //Set Values
        CountryText.setText(country.name);
    
        //End
        return CustomView;
    }
    }
    

    国家级

    public class Country {
    public String id, name, image;
    
    public Country (String id, String name, String image) {
        this.id = id;
        this.name = name;
        this.image = image;
    }
    }
    

    这是当前阻止我继续的唯一问题,因为在此之后出现的功能要求用户访问ListView。我一整天都在努力使这项工作真正发挥作用。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Pavneet_Singh    6 年前

    您没有在适配器中初始化列表实例,请执行以下操作

    public class CustomAdapter extends ArrayAdapter<Country>{
    
        public ArrayList<Country> ArrayListCountries;
    
        public CustomAdapter(@NonNull Context context,int resource, ArrayList<Country> Countries) {
            super(context, R.layout.activity_main_list, Countries);
            ArrayListCountries = Countries;
           //^^^^^^^^^^^^^^^^^^^^^^^^^^^
        }
    //...
    }
    

    当您将列表传递给数组适配器时, super 调用以便直接使用 getItem(int)

    Country country = getItem(Position);
    

    注意:将命名约定与引用统计信息一起使用是理想的,小写为 arrayListCountries countries