我在使用自定义Spinner
刷新Adapter
时遇到问题。自定义适配器显示“名称”,但可以引用所有对象数据(例如“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;
}
}
}
答案 0 :(得分:0)
默认情况下,适配器不会监听数据集,当数据集更改时,您必须将新数据传递给适配器并触发更新。
您需要在适配器内部更新它,更新和适配器始终是一个两步过程。 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那样华丽,但使用起来非常简单,而且非常适合你的任务。
答案 1 :(得分:0)
我建议在适配器上调用notifyDataSetChanged
。 myAdapter.notifyDataSetChanged();
。这将通知您的微调器数据集已更改,并且美国应相应更新。