片段不刷新其内容

Posted

技术标签:

【中文标题】片段不刷新其内容【英文标题】:Fragment does not refresh its content 【发布时间】:2012-12-17 02:13:45 【问题描述】:

在下面的代码中,我设置了一个显示 2 个 ListViews 的片段。

当主Activity调用Fragment方法时:

 prendiListaBest

 prendiListaWorst

他们在适配器上调用 notifyDataSetChanged(),

因此列表应该使用 ArrayLists 的新内容进行更新。

但这不会发生。

欢迎任何帮助和建议

public class WorstBest extends Fragment 
    public ListView lvBest;
public ListView lvWorst;
public MyAdapter myAdap;
public MyAdapter myAdap2;
public ArrayList<Stock> best;
public ArrayList<Stock> worst;
public View v;
   @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) 
        v= inflater.inflate(R.layout.listaworstbest, container, false);    
        lvBest= (ListView)v.findViewById(R.id.listbest);
        lvWorst=(ListView)v.findViewById(R.id.listworst);;
        myAdap= new MyAdapter(best, getActivity());
        myAdap2= new MyAdapter(worst, getActivity());
        lvBest.setAdapter(myAdap);
        lvWorst.setAdapter(myAdap2);
        return v;              
    

    public void prendiListaBest(ArrayList<Stock> al)
        Log.e("", "passo per prendilitsa del fragment worstbest");
        best=al;
        Log.e("", "nel fragment best è" + Integer.toString(best.size()));
        myAdap.notifyDataSetChanged();
        

    public void prendiListaWorst(ArrayList<Stock> al)
        Log.e("", "passo per prendilitsa del fragment worstbest");
        worst=al;
        Log.e("", "nel fragment worst è" + Integer.toString(worst.size()));
        myAdap2.notifyDataSetChanged();
    

    @Override
    public void onCreate(Bundle savedInstanceState)
        super.onCreate(savedInstanceState);
    

这是我的自定义适配器的代码。 我按要求发布了,但我很抱歉,因为它真的很乱:

public class MyAdapter extends BaseAdapter   
    ArrayList<Stock> l; 
    Activity a;

public MyAdapter(ArrayList<Stock> li, Activity ac) 
        // TODO Auto-generated constructor stub
    l = li;
    a=ac;


public View getView(int position, View convertView, ViewGroup parent) 
    View row=convertView;

    if (row==null) 
    LayoutInflater inflater=a.getLayoutInflater();
    row=inflater.inflate(R.layout.row, parent, false);
       
    TextView tw=(TextView)row.findViewById(R.id.textView1);

    String st=l.get(position).simbolo;
    String st1=st;
    String st2=st;
    String st3=st;
    String st4=st;
    String st5=st;
    String st6=st;
    String st7=st;
    String st8=st;
    st8=st;
        if(st.length()<=7)st1=st.concat("     ");st2=st1;st3=st1;st4=st1;st5=st1;st6=st1;st7=st1;st8=st1;
    if(st1.length()<=7)st2=st1.concat("     ");st3=st2;st4=st2;st5=st2;st6=st2;st7=st2;st8=st2;
    if(st2.length()<=7)st3=st2.concat(" ");st4=st3;st5=st3;st6=st3;st7=st3;st8=st3;
    if(st3.length()<=7)st4=st3.concat(" ");st5=st4;st6=st4;st7=st4;st8=st4;
    if(st4.length()<=7)st5=st4.concat(" ");st6=st5;st7=st5;st8=st5;
    if(st5.length()<=7)st6=st5.concat(" ");st7=st6;st8=st6;
    if(st6.length()<=7)st7=st6.concat(" ");st8=st7;
    if(st7.length()<=7)st8=st7.concat(" ");

    tw.setText(st8);
    String allora=(String) tw.getText();    
    TextView tw2=(TextView)row.findViewById(R.id.nome);
    ///aggiungiamo numero minimo caratteri
    tw2.setText((l.get(position).nome));
    ///
    TextView tw3=(TextView)row.findViewById(R.id.prezzo);
    tw3.setText((l.get(position).prezzo));

    TextView tw4=(TextView)row.findViewById(R.id.cambiamento);
    tw4.setText((l.get(position).cambiamento).concat(" %"));

    try 
    double value = Double.parseDouble(l.get(position).cambiamento);
    if(value<0)tw4.setTextColor(Color.RED);
    if(value>0)tw4.setTextColor(Color.GREEN);
    TextView tw5=(TextView)row.findViewById(R.id.freccia);
    if(value<0)tw5.setText("▼");
    if(value>0)tw5.setText("▲");
    if(value<0)tw5.setTextColor(Color.RED);
    if(value>0)tw5.setTextColor(Color.GREEN);
         catch (Exception exc) 

    return row; 

 

 public int getCount() 
    // TODO Auto-generated method stub
    return l .size();



 public Object getItem(int position) 
    // TODO Auto-generated method stub
    return l .get(position);

 

 public long getItemId(int position) 
    // TODO Auto-generated method stub
    return position;
 
 

编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑编辑/em>

非常感谢,这个答案很有道理。**

但我不明白为什么同一个适配器适用于以下片段;我解释: 下面的“listafragment”片段有类似的逻辑,它使用了

 prendiLista

获取最新版本的方法

 ListArray lt

与之前的“WorstBest”片段中的处理方式完全相同。 但在这种情况下,当

    public void prendiLista(ArrayList<Stock> al)
        lt=al;
         myAdap.notifyDataSetChanged();
        

视图已更新!!!

请问有什么区别??? :-)

据我了解,调用 notifyDataSetChanged() 足以更新视图!!

还是非常感谢! (明天早上我会接受答案)。

 public class listafragment extends Fragment 
    public ListView lv;
    public MyAdapter myAdap;
    public ArrayList<Stock> lt;
    public View v;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) 
         // Inflate the layout for this fragment
        View v= inflater.inflate(R.layout.lista, container, false);    
        lv= (ListView) v.findViewById(android.R.id.list);
        if(lv==null)Log.e("","nel fragment la lista è nulla");
         if(lv!=null)Log.e("","nel fragment la lista NON è nulla"); 
         myAdap= new MyAdapter(lt, getActivity()); 
         lv.setAdapter(myAdap);             
        return v;
    

    public void prendiLista(ArrayList<Stock> al)
        Log.e("", "passo per prendilitsa del fragment");
        lt=al;
        if(myAdap==null)Log.e("","nel prendilista del fragment myadapt è     nullo");;
        myAdap.notifyDataSetChanged();
                     
       public void addToFavorites(int pos)
         Quotes.addToFavorites(pos);

     

     @Override
    public void onCreate(Bundle savedInstanceState)
        lt=Quotes.dammi();
        super.onCreate(savedInstanceState);
    

【问题讨论】:

看起来您有自定义适配器。您可以发布这些课程的代码吗?也许您没有正确实现 notifyDataSetChanged。 【参考方案1】:

因此列表应该使用 ArrayLists 的新内容进行更新。

很遗憾,没有。当您的应用首次运行时,lbest 都引用了相同的数据。你已经设置好了。

Fragment:
    best ---\
            |
            |--- <the initial data>
Adapter:    |
    l ------/

但是在你拨打best=al之后,你有:

Fragment:
    best ------- <the new data>

Adapter:    
    l ---------- <the initial data>

因此,您永远不会更新适配器中的引用。向自定义适配器添加新方法以更改 l 使用 l 本身,因为您没有将其声明为 private

public void prendiListaBest(ArrayList<Stock> al)
    myAdap.l=al;
    myAdap.notifyDataSetChanged();
    

【讨论】:

答案是正确的,但更封装的方法是使用适配器的公共方法来重新填充其内部列表:***.com/a/12662994/693752 我同意并在我的回答中提出了相同的技术。我希望这段代码展示了l 的暴露程度,但我觉得答案已经足够长了...... @Sam 非常感谢!但是请你介意看看我的编辑,我有一些困惑,尽管你的回答完全有道理? (无论如何我明天早上都会接受答案)。再次感谢。 @pietmau 这令人困惑。你要在其他地方更改Quotes.dammi() 吗? @Sam 谢谢山姆。我正在调用主 Activity 方法 lt=Quotes.dammi() 以在开始时检索数据集(它在 onCreate ...)之后,当数据集更改时,主 Activity 调用 prendiLista(ArrayList&lt;Stock&gt; al) 以通知数据已更改。它有效......再次感谢

以上是关于片段不刷新其内容的主要内容,如果未能解决你的问题,请参考以下文章

如何刷新其活动的 MenuitemSelected 上的片段?

为啥对话框会在不刷新的情况下删除其内容?

WPF数据绑定,属性值更改UI不刷新其内容[重复]

使数据缓存的特定区域无效而不刷新其内容

数据变化时刷新 Fragment 内容的方法(如调用 onCreateView)

为什么对话框会在不刷新的情况下删除其内容