从ListView当前项目观察LiveData

时间:2019-05-25 14:48:14

标签: android-fragments android-listview android-adapter android-livedata android-viewmodel

基本上我想检索从当前ListViewItem生成的int(分数),并将其分配回我的ListView中的具体TextView。我正在将SharedViewModel与LiveData一起使用,但是当我什么也没看到时。我正在将Nav Architecture Component与Single活动。如果有人帮忙,我会很高兴。谢谢您,这里有一些代码。

公共类ListFrag扩展了片段{

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

    model.getCurrentScore().observe(getViewLifecycleOwner(), new Observer<Integer>() {
        @Override
        public void onChanged(@Nullable Integer s) {

            for (int i = 0; i < myListView.getAdapter().getCount(); i++) {

                v =  myListView.getAdapter().getView(i,null, myListView);

                finalScore = v.findViewById(R.id.finalScoreView);

                    if (s != null) {
    itemAdapter = new ItemAdapter(getActivity(),items,bushido,description,s,finalScore);
                        myListView.setAdapter(itemAdapter);
                       finalScore.setText(String.valueOf(s));

                    }
      ((BaseAdapter)myListView.getAdapter()).notifyDataSetChanged();
            }
        }
    });
}

公共类SharedViewModel扩展了ViewModel {

private MutableLiveData<Integer> currentScore = new MutableLiveData<>();

public LiveData<Integer> getCurrentScore(){
    return currentScore;
}

public void setCurrentScore(Integer finito) {
    currentScore.setValue(finito);

}

}

公共类ItemAdapter扩展了BaseAdapter {

LayoutInflater mInflater;
String[] items;
String[] bushido;
String[] description;
 TextView finalscorre;
Integer scr;

public ItemAdapter(Context c,String[] i ,String [] p ,String[] d, Integer scc,TextView sc) {
    items = i;
    bushido = p;
    description = d;
    finalscorre = sc;
    scr = scc;
    mInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
    return items.length;
}

@Override
public Object getItem(int i) {
    return items[i];
}

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

@Override
public View getView(int i, View convertView, ViewGroup parent) {
    View v = mInflater.inflate(R.layout.my_listview_detail, null);
    TextView nameTextView = v.findViewById(R.id.NameTextView);
    TextView bushidoTextView = v.findViewById(R.id.bushidoTextView);
    TextView descriptionTextView = v.findViewById(R.id.descriptionTextView);
    finalscorre = v.findViewById(R.id.finalScoreView);

    String name = items[i];
    String desc = description[i];
    String bush = bushido[i];


    finalscorre.setText("Waat");
    nameTextView.setText(name);
    descriptionTextView.setText(desc);
    bushidoTextView.setText(bush);

    ItemAdapter.this.notifyDataSetChanged();

    return v;
}

}

当我尝试从ListView中分配TextView中的LiveData时,它可以工作。但是,当我尝试此操作时,什么也没有发生(没有错误,也没有结果)。

2 个答案:

答案 0 :(得分:0)

在适配器内部,您什么都不做,只会更新LiveData

答案 1 :(得分:0)

适配器充当数据(在您的情况下,您传递给适配器的字符串数组)和ListView(在您的情况下,myListView)之间的桥梁。对ListView的任何更改都需要遵循以下步骤:

  • 对数据本身进行所需的更改
  • 将此新数据传递给适配器
  • 适配器更新列表视图

我已经写了一些示例代码:

ItemAdapter

public class ItemAdapter extends BaseAdapter {

    LayoutInflater mInflater;
    String[] items;
    String[] bushido;
    String[] description;
    // TextView finalscorre; // I commented out this TextView please see the comment below
    Integer scr;

    public ItemAdapter(Context c,String[] i ,String [] p ,String[] d, Integer scc,TextView sc) {
        items = i;
        bushido = p;
        description = d;
        // finalscorre = sc;
        scr = scc;
        mInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void updateItems(String[] i, String[] p, String[] d, Integer scc) {
        items = i;
        bushido = p;
        description = d;
        scr = scc;

        // notify the adapter to refresh the list view.
        notifyDataSetChanged()
    }

    @Override
    public int getCount() {
        return items.length;
    }

    @Override
    public Object getItem(int i) {
        return items[i];
    }

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

    @Override
    public View getView(int i, View convertView, ViewGroup parent) {
        View v = mInflater.inflate(R.layout.my_listview_detail, null);
        TextView nameTextView = v.findViewById(R.id.NameTextView);
        TextView bushidoTextView = v.findViewById(R.id.bushidoTextView);
        TextView descriptionTextView = v.findViewById(R.id.descriptionTextView);
        //finalscorre = v.findViewById(R.id.finalScoreView);
        TextView finalscorre = v.findViewById(R.id.finalScoreView);


        String name = items[i];
        String desc = description[i];
        String bush = bushido[i];


        // finalscorre.setText("Waat");
        finalscorre.setText(scr);
        nameTextView.setText(name);
        descriptionTextView.setText(desc);
        bushidoTextView.setText(bush);

        // ItemAdapter.this.notifyDataSetChanged(); Do NOT call this method inside getView

        return v;
    }
}

片段

public class ListFrag extends Fragment {

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Create and set adapter just once. Do not create or set new adapter in observer, for loop, etc.
        itemAdapter = new ItemAdapter(getActivity(),items,bushido,description,s,finalScore);
        myListView.setAdapter(itemAdapter);

        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

        model.getCurrentScore().observe(getViewLifecycleOwner(), new Observer<Integer>() {
            @Override
            public void onChanged(@Nullable Integer s) {
                itemAdapter.updateItems(items,bushido,description,s);
            }
        });
    }
}

我无法弄清楚finalscorre应该是什么,因此我假设这是存储您提到的最终分数的文本视图,并且所有列表视图项都应具有相同的值。如果不是这种情况,请在您的问题中加以澄清。

还请注意,尽管此解决方案足以解决您提到的特定问题,但它们可以进行其他一些改进:

  • 使用RecyclerView代替ListView
  • 代替维护多个String[],而是定义一个代表项并具有单个数组的POJO。

此外,在Google示例中选中此adapter implementation也会有所帮助。