【问题标题】:Refreshing Spinner after Asyctask with custom objects使用自定义对象在 Asyctask 之后刷新 Spinner
【发布时间】:2017-07-15 11:21:38
【问题描述】:

我在使用自定义 Adapter 刷新我的 Spinner 时遇到问题。自定义适配器显示“名称”,但可以引用所有对象数据(例如“ID”、“年龄”)。

我使用 Asynctask 将在线数据导入为 JSON 并将它们存储在 SQLite 数据库中。

在我的MainActivity 中,我有一个带有自定义对象的Spinner。 现在我尝试了很多,但在使用“onPostExecute”更新 SQLite 数据库后未能更新 spinneradapter。

我将跳过一些正在运行且不应该影响的代码部分(导入、抓取数据、数据库内容……)以保持干净。

这是我的课程

users.java

package domain.project;

public class user{
    private String name;
    private int age;
    private long id;

public User(String name, int age, long id) {
        this.name = name;
        this.age= age;
        this.id = id;

    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }


    @Override
    public String toString() {
        String output = name;
        return output;
    }
}

UserDataSource.java

package domain.project;

// imports skipped

public class UserDataSource {

    private SQLiteDatabase database;

    public UserDataSource(Context context) {

    }
    public void open() {

       //Open database stuff

    }

    public void close() {
        //closing database stuff
    }

    public User createUser(String name, int age) {

        //writing users into SQLitedatabase stuff

        cursor.moveToFirst();
        User user = cursorToUser(cursor);
        cursor.close();

        return user;
    }

    public void deleteUser(User user) {
        //delete user from SQLitedatabase
    }

    public void refreshUser() {

        GetUsersTask getUsersTask = new GetUsersTask();
        getUsersTask.execute("Users");

    }

    public User updateUser(long id, String newName, int newAge) {
        //update User in SQLitedatabase
    }

    private User cursorToUser (Cursor cursor) {
        //getting User from SQLite Database

        User user = new User(name, age, id);

        return user;
    }


    public User[] allUsers() {
        {
        //filling Array with all Users from SQLitedatabase
        }
        return allUsers;
    }

    public class GetUsersTask extends AsyncTask<String, Integer, String[]> {

       private String[] readJsonUser(String jsonString) {

            try {
                JSONArray jArray = new JSONArray(jsonString);
                String[] returnArray = new String[jArray.length()];

                //parsing JSON String to Array

                }
                return returnArray ;

            } catch (final JSONException e) {

            }
            return null;
        }

        @Override
        protected String[] doInBackground(String... strings) {

            if (strings.length == 0) { 
                return null;
            }

            // grabbing JSON string from web and store it in userJsonString


            return readJsonUser(userJsonString);
        }


        @Override
        protected void onProgressUpdate(Integer... values) {

        }

        @Override
        protected void onPostExecute(String[] strings) {

            if (strings != null) {
                //write and update SQLite database

                }
            }
        }
    }

}

MainActivity.java

package domain.project;

//skipping the imports

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dataSource = new UserDataSource(this);

    }

    @Override
    protected void onResume() {
        super.onResume();
        showAllListEntries();
    }

    @Override
    protected void onPause() {
        super.onPause();
        dataSource.close();
    }

    public void showAllListEntries() {

        final Spinner sqlUserSpinner = (Spinner) findViewById(R.id.spinner_user);
        final SpinAdapter userSpinAdapter = new SpinAdapter(this, android.R.layout.simple_spinner_dropdown_item, dataSource.allUsers());


        usersSpinner.setAdapter(userSpinAdapter);

        usersSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            public void onItemSelected(AdapterView<?> adapterView,
                                       View view, int i, long l) {
                // Testing the selected Item
                User user = userSpinAdapter.getItem(i);
                Toast.makeText(MainActivity.this, "Selected : " + user.getId() + "<-ID   age->" + user.getAge(), Toast.LENGTH_SHORT).show();

            }
            public void onNothingSelected(AdapterView<?> arg0) {


            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }



    public class SpinAdapter extends ArrayAdapter<User>{

        private Context context;
        private User[] values;

        public SpinAdapter(Context context, int textViewResourceId,
                           User[] values) {
            super(context, textViewResourceId, values);
            this.context = context;
            this.values = values;
        }

        public int getCount(){
            return values.length;
        }

        public SQLShot getItem(int position){
            return values[position];
        }

        public long getItemId(int position){
            return position;
        }


        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            TextView label = new TextView(context);
            label.setTextColor(Color.BLACK);
            label.setText(values[position].getName());
            return label;
        }

        @Override
        public View getDropDownView(int position, View convertView,
                                    ViewGroup parent) {
            TextView label = (TextView) super.getView(position, convertView, parent);
            label.setTextColor(Color.BLACK);
            label.setText(values[position].getName());

            return label;
        }
    }

}

【问题讨论】:

    标签: android android-asynctask android-spinner android-adapter


    【解决方案1】:

    我建议在您的适配器上调用notifyDataSetChangedmyAdapter.notifyDataSetChanged();。这将通知您的微调器数据集已更改,美国应相应更新。

    【讨论】:

      【解决方案2】:

      适配器默认不监听数据集,当数据集更改时,您必须将新数据传递给适配器并触发更新。

      您需要在适配器内部使用一种方法来更新它,更新和适配器始终是一个两步过程。 1. 更新您的数据。 2. 告诉适配器。

      在您的适配器内部创建:

      public void update(List<String> data) {
        adapterDataList.clear();
        adapterDataList.addAll(data);
        notifyDatasetChanged();
      }
      

      您正在使用数组,我强烈建议您使用列表。数组有一个固定的大小,这会给你带来更多的问题。

      notifyDatasetChanged()方法让适配器知道数据列表的变化。

      由于您直接使用 SQL,您可以查看 CursorAdapter。

      如果你想要自动更新数据,Realm 可以做到这一点。他们甚至有一个适配器。 Realm 是一个 ORM,我推荐一个 ORM 而不是原生的 OpenHelper。另一个不错的 ORM 是 Sugar ORM,它不像 Realm 那样花哨,但使用起来非常简单,足以胜任您的任务。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多