简体   繁体   English

ListView不想刷新

[英]ListView doesn't want to refresh

I have one problem, I have one activity and one dialogfragment. 我有一个问题,我有一个活动和一个dialogfragment。 When I click on button in my dialogfragment I send model to Activity and write this model to the list. 当我在对话框片段中单击按钮时,我将模型发送给Activity并将该模型写入列表。 But when I add to the list more than one element, my listview duplicate first element, I init my adapter in onCreate() and add new information in onExcerciseAdd : 但是,当我向列表添加多个元素时,我的listview复制了第一个元素,我在onCreate()初始化适配器,并在onExcerciseAdd添加新信息:
Activity: 活动:

public class AddTrainingActivity extends ActionBarActivity implements ExcercisesFragment.onButtonAdd {
private ActionBarDrawerToggle toggle;
int DIALOG_TIME = 1;
int myHour = 00;
int myMinute = 00;
TextView tvTime;
Button btn_add_ex;
ListView list;
ExcerciseAdapter adapter;
ArrayList<ExcerciseModel> excercise_list;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_addtraining);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    tvTime = (TextView) findViewById(R.id.tv_time_add);
    tvTime.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showDialog(DIALOG_TIME);
        }
    });
    btn_add_ex = (Button) findViewById(R.id.btn_add_exercise);
    list = (ListView) findViewById(R.id.list_excercise);
    excercise_list = new ArrayList<ExcerciseModel>();
    Log.d("onCreate", "Work!");
    adapter = new ExcerciseAdapter(excercise_list, this);
    btn_add_ex.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ExcercisesFragment dlg = new ExcercisesFragment();
            dlg.show(getSupportFragmentManager(),"dlg");
        }
    });
}

protected Dialog onCreateDialog(int id) {
    if (id == DIALOG_TIME) {
        Calendar c = Calendar.getInstance();
        myHour = c.getTime().getHours();
        myMinute = c.getTime().getMinutes();
        TimePickerDialog tpd = new TimePickerDialog(this, myCallBack, myHour, myMinute, true);
        return tpd;
    }
    return super.onCreateDialog(id);
}

TimePickerDialog.OnTimeSetListener myCallBack = new TimePickerDialog.OnTimeSetListener() {
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        myHour = hourOfDay;
        myMinute = minute;
        if (myMinute < 10) {
            tvTime.setText(myHour + " : 0" + myMinute );
        } else {
            tvTime.setText(myHour + " : " + myMinute );
        }
        Log.d("TIME", "minutes " + myMinute);
    }
};


@Override
public void onExcerciseAdd(ExcerciseModel model) {
    Log.d("Adapter", "null? " + (adapter.isEmpty()));
    excercise_list.add(model);
    if (adapter.isEmpty()) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                adapter.notifyDataSetInvalidated();
                adapter.notifyDataSetChanged();
                list.invalidate();
                list.invalidateViews();
            }
        });

    }
    list.setAdapter(adapter);
    for (int i = 0; i < excercise_list.size(); i++){
        Log.d("List_ex", "list(" + i +"): " + excercise_list.get(i).getTitle().toString());
    }
}
}

Dialogfragment: Dialogfragment:

public class ExcercisesFragment extends DialogFragment {

private Button btn_add_dialog;
private EditText edit_time;
private EditText edit_count1;
private EditText edit_count2;
private EditText edit_weight;
private AutoCompleteTextView edit_ex;

public interface onButtonAdd {
    void onExcerciseAdd (ExcerciseModel model);

}

onButtonAdd button_add;

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    getDialog().setTitle("Title!");
    View v = inflater.inflate(R.layout.fragment_add_excersise, null);
    btn_add_dialog = (Button) v.findViewById(R.id.btn_add_exercise_fr);
    edit_time = (EditText) v.findViewById(R.id.edit_ex_go);
    edit_count1 = (EditText) v.findViewById(R.id.edit_podh);
    edit_count2 = (EditText) v.findViewById(R.id.edit_repeat);
    edit_weight = (EditText) v.findViewById(R.id.edit_weight_add);
    edit_ex = (AutoCompleteTextView) v.findViewById(R.id.excercise_title);
    button_add = (onButtonAdd) getActivity();
    Resources res = getResources();
    String[] excersices = res.getStringArray(R.array.excersices);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
            R.layout.profile_item, R.id.item_autotext, excersices);
    adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
    edit_ex.setAdapter(adapter);
    edit_ex.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_ENTER) {
                // Just ignore the [Enter] key
                return true;
            }
            // Handle all other keys in the default way
            return false;
        }
    });
    edit_ex.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            edit_ex.showDropDown();
        }
    });
    btn_add_dialog.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String time = edit_time.getText().toString();
            String title = edit_ex.getText().toString();
            String weight = edit_weight.getText().toString();
            String count1 = edit_count1.getText().toString();
            String count2 = edit_count2.getText().toString();
            if (title.equals("") || count1.equals("") || count2.equals("") || weight.equals("") || time.equals("")) {
                Toast.makeText(getActivity(),"Необходимо заполнить все поля", Toast.LENGTH_SHORT).show();
            } else {
                ExcerciseModel model = new ExcerciseModel();
                model.setTitle(edit_ex.getText().toString());
                model.setTime(Integer.parseInt(edit_time.getText().toString()));
                model.setPodh(Integer.parseInt(edit_count1.getText().toString()));
                model.setCount(Integer.parseInt(edit_count2.getText().toString()));
                model.setWeight(Integer.parseInt(edit_weight.getText().toString()));
                button_add.onExcerciseAdd(model);
                dismiss();
            }
        }
    });
    return v;
}
}

and Adapter: 和适配器:

public class ExcerciseAdapter extends BaseAdapter {

ArrayList<ExcerciseModel> list;
Activity context;


public ExcerciseAdapter (ArrayList<ExcerciseModel> list, Activity context) {
    this.list = list;
    this.context = context;
}
@Override
public int getCount() {
    return list.size();
}

@Override
public Object getItem(int position) {
    return null;
}

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

private class ViewHolder {
    TextView txtViewTitle;
    TextView txtViewTime;
    TextView txtViewPodh;
    TextView txtViewCount;
    TextView txtViewWeight;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    LayoutInflater inflater = context.getLayoutInflater();
    Log.d("ConvertView", "convertview is null " + (convertView == null));
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.list_item_ex, null);
        holder = new ViewHolder();
        holder.txtViewTitle = (TextView) convertView.findViewById(R.id.tv_adapter_title);
        holder.txtViewTime = (TextView) convertView.findViewById(R.id.tv_adapter_time_get);
        holder.txtViewPodh = (TextView) convertView.findViewById(R.id.tv_adapter_podh_get);
        holder.txtViewCount = (TextView) convertView.findViewById(R.id.tv_adapter_count_get);
        holder.txtViewWeight = (TextView) convertView.findViewById(R.id.tv_adapter_weight_get);
        holder.txtViewTitle.setText(list.get(position).getTitle().toString());
        holder.txtViewTime.setText(String.valueOf(list.get(position).getTime()));
        holder.txtViewPodh.setText(String.valueOf(list.get(position).getPodh()));
        holder.txtViewCount.setText(String.valueOf(list.get(position).getCount()));
        holder.txtViewWeight.setText(String.valueOf(list.get(position).getWeight()));
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    Log.d("Adapter", "List_size = " +list.size());
    Log.d("Adapter", "Title(" + position + "): " + list.get(position).getTitle().toString());
    return convertView;
}
}

I don't know, but Adatper calls too many times, when I add one element it's calls 3 times. 我不知道,但是Adatper调用太多次,当我添加一个元素时,它调用了3次。 Please help me with this problem. 请帮我解决这个问题。

You only update your list items when you are creating them. 仅在创建列表项时更新它们。 You should do something like this: 您应该执行以下操作:

LayoutInflater inflater = context.getLayoutInflater();
View view = (convertView == null)? inflater.inflate(R.layout.list_item_ex, parent, false) : convertView;

holder = new ViewHolder();
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.tv_adapter_title);
holder.txtViewTime = (TextView) convertView.findViewById(R.id.tv_adapter_time_get);
holder.txtViewPodh = (TextView) convertView.findViewById(R.id.tv_adapter_podh_get);
holder.txtViewCount = (TextView) convertView.findViewById(R.id.tv_adapter_count_get);
holder.txtViewWeight = (TextView) convertView.findViewById(R.id.tv_adapter_weight_get);
holder.txtViewTitle.setText(list.get(position).getTitle().toString());
holder.txtViewTime.setText(String.valueOf(list.get(position).getTime()));
holder.txtViewPodh.setText(String.valueOf(list.get(position).getPodh()));
holder.txtViewCount.setText(String.valueOf(list.get(position).getCount()));
holder.txtViewWeight.setText(String.valueOf(list.get(position).getWeight())); 

return view;

Also you don't need to call all of these methods when changing the data set 另外,更改数据集时无需调用所有这些方法。

    adapter.notifyDataSetInvalidated();
    adapter.notifyDataSetChanged();
    list.invalidate();
    list.invalidateViews();

Calling adapter.notifyDataSetChanged(); 调用adapter.notifyDataSetChanged(); should be enough 应该足够了

You also don't need to reset the adapter every time you change the data, so this line can also be removed 您也不需要每次更改数据都重置适配器,因此也可以删除此行

list.setAdapter(adapter);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM