0

我正在開發應用程序,該應用程序應該顯示會議的會話列表,而另一個列表僅包含會議的文件。鏡像複選框與Android的不同片段狀態

我貼幾張截圖這樣一個問題:Save checkboxes states through fragments in Android

我的目標是能夠也«鏡»的複選框狀態在兩個列表,這樣,如果紙張在會談名單核對,它在論文列表中被檢查。

你有什麼想法我可以做到這一點?

該列表是使用兩個片段與自己的適配器實現的。

這裏是我的代碼:

主要活動:

package be.unamur.confpers; 
public class MainActivity extends FragmentActivity implements ActionBar.TabListener { 

private ViewPager viewPager; 
private TabsPagerAdapter mAdapter; 
private ActionBar actionBar; 
SqlHandler sqlHandler; 
// Tab titles 
private String[] tabs = { "Talks", "Papers", "Ma sélection"}; 

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

    // Initialization database 
    sqlHandler = new SqlHandler(this); 

    viewPager = (ViewPager) findViewById(R.id.pager); 
    actionBar = getActionBar(); 
    mAdapter = new TabsPagerAdapter(getSupportFragmentManager()); 

    viewPager.setAdapter(mAdapter); 
    actionBar.setHomeButtonEnabled(false); 
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  

    // Adding Tabs 
    for (String tab_name : tabs) { 
     actionBar.addTab(actionBar.newTab().setText(tab_name) 
       .setTabListener(this)); 
    } 

    /** 
    * on swiping the viewpager make respective tab selected 
    * */ 
    viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 

     @Override 
     public void onPageSelected(int position) { 
      // on changing the page 
      // make respected tab selected 
      actionBar.setSelectedNavigationItem(position); 
     } 

     @Override 
     public void onPageScrolled(int arg0, float arg1, int arg2) { 
     } 

     @Override 
     public void onPageScrollStateChanged(int arg0) { 
     } 
    }); 
} 

@Override 
public void onTabReselected(Tab tab, FragmentTransaction ft) { 
} 

@Override 
public void onTabSelected(Tab tab, FragmentTransaction ft) { 
    // on tab selected 
    // show respected fragment view 
    viewPager.setCurrentItem(tab.getPosition()); 
} 

@Override 
public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
} 



} 

TalksFragment:

public class TalksFragment extends Fragment { 

private TalkAdapter talkAdapter; 
List<Talk> talks; 

private List<Talk> talksParser(){ 

    try{ 
     XMLParser parser = new XMLParser(); 
     talks = parser.parse(getActivity().getApplicationContext().getAssets().open("talks.xml")); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return talks; 
}; 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 

    View v = inflater.inflate(R.layout.fragment_talks, container, false); 

    ExpandableListView lv = (ExpandableListView) v.findViewById(R.id.listTalks); 
    talks = talksParser(); 
    talkAdapter = new TalkAdapter (getActivity(),talks); 
    lv.setAdapter(talkAdapter); 


    return v; 
} 
} 

TalkAdapter:

public class TalkAdapter extends BaseExpandableListAdapter { 

private Context context; 
private List<Talk> talks; 
private LayoutInflater inflater; 
private Button changeScreen; 

int checked = 0; 
CheckBox cb; 



public TalkAdapter(Context context, 
     List<Talk> talks) { 
    this.context = context; 
    this.talks = talks; 
    inflater = LayoutInflater.from(context); 
} 

public Paper getChild(int groupPosition, int childPosition) { 
    return talks.get(groupPosition).getPapers().get(childPosition); 
} 

public long getChildId(int groupPosition, int childPosition) { 
    return (long)(groupPosition*1024+childPosition); // Max 1024 children per group 
} 

private class ViewHolder { 
    TextView title; 
    TextView author; 
    CheckBox name; 
} 


public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { 
    View v = null; 
    ViewHolder holder = null; 

    if(convertView == null){ 
     v = inflater.inflate(R.layout.child_row, parent, false); 
     Paper p = getChild(groupPosition, childPosition); 

     cb = (CheckBox)v.findViewById(R.id.check1); 
     //cb.setChecked(p.getState()); 

     TextView paper = (TextView)v.findViewById(R.id.papername); 
     if(paper != null) 
      paper.setText(p.getTitle()); 

     TextView author = (TextView)v.findViewById(R.id.authorname); 
     if(author!= null) 
      author.setText(p.getAuthor()); 

     holder = new ViewHolder(); 
     holder.name = (CheckBox) v.findViewById(R.id.check1); 
     holder.title = (TextView) v.findViewById(R.id.papername); 
     holder.author= (TextView) v.findViewById(R.id.authorname); 
     v.setTag(holder); 

     holder.name.setOnClickListener(new View.OnClickListener() { 

      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       CheckBox cb = (CheckBox) v; 
       Paper paper = (Paper) cb.getTag(); 
       String title = paper.getTitle(); 
       String author = paper.getAuthor(); 
       if (cb.isChecked()){ 
        Toast.makeText(context, "Papier "+title+ " ajouté", Toast.LENGTH_SHORT).show(); 
        //String query = "INSERT INTO SELECTED_PAPERS(title,author) values ('" 
        //+ title +"','" + author +"')"; 
        //sqlHandler.executeQuery(query); 

       } 
       if (cb.isChecked()==false){ 
        Toast.makeText(context, "Papier "+title+ " retiré", Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }); 
    } 

    else{ 
     v = convertView; 
     holder = (ViewHolder) v.getTag(); 
    } 

    Paper paper = getChild(groupPosition, childPosition); 
    holder.author.setText(paper.getAuthor()); 
    holder.title.setText(paper.getTitle()); 
    holder.name.setTag(paper); 

    return v; 


} 

public int getChildrenCount(int groupPosition) { 
    return talks.get(groupPosition).getPapers().size(); 
} 

public Talk getGroup(int groupPosition) { 
    return talks.get(groupPosition);   
} 

public int getGroupCount() { 
    return talks.size(); 
} 

public long getGroupId(int groupPosition) { 
    return (long)(groupPosition*1024); // To be consistent with getChildId 
} 

public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 
    View v = null; 
    if(convertView != null) 
     v = convertView; 
    else 
     v = inflater.inflate(R.layout.group_row, parent, false); 
    Talk t = getGroup(groupPosition); 
    TextView colorGroup = (TextView)v.findViewById(R.id.papername); 
    if(t != null) 
     colorGroup.setText(t.getName()); 


    return v; 
} 



public boolean hasStableIds() { 
    return true; 
} 

public boolean isChildSelectable(int groupPosition, int childPosition) { 
    return true; 
} 

public void onGroupCollapsed (int groupPosition) {} 
public void onGroupExpanded(int groupPosition) {} 


} 

PapersFragment:

public class PapersFragment extends Fragment { 

private PaperAdapter listAdapter; 
private Context myContext; 
List<Paper> papers = null; 




private List<Paper> papersParser() { 

    try { 
     XMLParser2 parser = new XMLParser2(); 
     papers = parser.parse(getActivity().getApplicationContext().getAssets().open("talks.xml")); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return papers; 
}; 



@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 

    View v = inflater.inflate(R.layout.fragment_papers, container, false); 

    ListView lv = (ListView) v.findViewById(R.id.list); 
    papers = papersParser(); 
    listAdapter = new PaperAdapter(getActivity(),papers); 
    lv.setAdapter(listAdapter); 
    lv.setOnItemClickListener(new OnItemClickListener(){ 
     public void onItemClick(AdapterView<?> parent, View view, 
       int position, long id) { 
      //Si un jour je veux mettre une description 
        } 
    }); 

    if (papers == null) { 
    Toast.makeText(getActivity().getApplicationContext(), "Papers vide", Toast.LENGTH_LONG).show(); 
    } 
    return v; 
} 
} 

PaperAdapter:

public class PaperAdapter extends BaseAdapter implements OnClickListener { 

private Context context; 
private List<Paper> papers; 
private LayoutInflater inflater; 
CheckBox cb; 
TextView paper; 
SqlHandler sqlHandler; 

public PaperAdapter(Context context, List<Paper> papers) { 
    this.context = context; 
    this.papers = papers; 
    inflater = LayoutInflater.from(context); 
} 

@Override 
public int getCount(){ 
    return papers.size(); 
} 

@Override 
public Object getItem(int position) { 
    return papers.get(position); 
} 

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

private class ViewHolder { 
    TextView title; 
    TextView author; 
    CheckBox name; 
} 

@Override 
public View getView(int position, View view, ViewGroup viewGroup) { 

    ViewHolder holder = null; 

    // We only create the view if its needed 
    if (view == null) { 
     view = inflater.inflate(R.layout.child_row, null); 

     // Set the click listener for the checkbox 
     //view.findViewById(R.id.check1).setOnClickListener(this); 


     Paper p = (Paper) getItem(position); 

     // Set the example text and the state of the checkbox 
     CheckBox cb = (CheckBox) view.findViewById(R.id.check1); 
     //cb.setChecked(p.isSelected()); 
     // We tag the data object to retrieve it on the click listener. 

     paper = (TextView)view.findViewById(R.id.papername); 
     if (paper != null) 
      paper.setText(p.getTitle()); 

     TextView author = (TextView)view.findViewById(R.id.authorname); 
     if(author!= null) 
      author.setText(p.getAuthor()); 

     holder = new ViewHolder(); 
     holder.name = (CheckBox) view.findViewById(R.id.check1); 
     holder.title = (TextView) view.findViewById(R.id.papername); 
     holder.author= (TextView) view.findViewById(R.id.authorname); 
     view.setTag(holder); 

     holder.name.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       CheckBox cb = (CheckBox) v; 
       Paper paper = (Paper) cb.getTag(); 
       String title = paper.getTitle(); 
       String author = paper.getAuthor(); 
       if (cb.isChecked()){ 
        Toast.makeText(context, "Papier "+title+ " ajouté", Toast.LENGTH_SHORT).show(); 
        //String query = "INSERT INTO SELECTED_PAPERS(title,author) values ('" 
          //+ title +"','" + author +"')"; 
        //sqlHandler.executeQuery(query); 

       } 
       if (cb.isChecked()==false){ 
        Toast.makeText(context, "Papier "+title+ " retiré", Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }); 
    } 
    else{ 
     holder = (ViewHolder) view.getTag(); 
    } 

    Paper paper = papers.get(position); 
    holder.author.setText(paper.getAuthor()); 
    holder.title.setText(paper.getTitle()); 
    holder.name.setTag(paper); 

    return view; 
} 

/*@Override 
/** Will be called when a checkbox has been clicked. */ 
public void onClick(View view, int position) { 
    /*TextView p = (TextView) view.findViewById(R.id.papername); 
    TextView a = (TextView) view.findViewById(R.id.authorname); 
    CheckBox cb = (CheckBox) view.findViewById(R.id.check1); 
    String title = p.getText().toString(); 
    String author = a.getText().toString(); 
    String query = "INSERT INTO SELECTED_PAPERS(title,author) values ('" 
      + title +"','" + author +"')"; 
    sqlHandler.executeQuery(query);*/ 
    //TextView p = (TextView) view.findViewById(R.id.papername); 
    //TextView a = (TextView) view.findViewById(R.id.authorname); 
    //String title = p.getText().toString(); 
    //String author = a.getText().toString(); 
    Paper p = (Paper) this.getItem(position); 
    String title = p.getTitle(); 
    Toast.makeText(context, "Papier ajouté", Toast.LENGTH_SHORT).show(); 

} 

@Override 
public void onClick(View arg0) { 
    // TODO Auto-generated method stub 

} 

/* 
private void savePrefs(String key, String checked) { 
    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 
    Editor edit = sp.edit(); 
    edit.putString (key, checked); 
    edit.commit(); 

}*/ 


} 

非常感謝!

+0

不確定問題是什麼? :) –

+0

我希望如果您在會談列表中查看«紙張»,它也會在紙張列表中檢查:) –

+0

看起來,您永遠無法同時打開兩個列表,所以問題是,爲什麼這些列表使用不同的數據源,如果你正在使用相同的講座。如果數據的顯示方式不同,數據源應該是相同的,因此當您選中一個框時,您會通知適配器數據已更改,而另一個片段應該立即將其提取出來,我認爲您採用的方法錯誤這就是爲什麼這個相對簡單的事情開始變得複雜。 –

回答

1

我很忙,但我會給你一些提示,幫助你向前邁進。

  1. 我不碰你的適配器,使其更簡單,但考慮統一儘可能多的,你可以,如果兩個名單幾乎相同,但不同的getView()方法,使用共同的抽象基類兩個適配器並實現每個不同的getView()。這只是一個例子。

  2. 請注意您通過的上下文。不要將活動傳遞給適配器。在這種特殊情況下,似乎沒有任何傷害,但片段由FragmentManager處理,並且適配器駐留在片段中,因此您可能會將內存泄漏一段時間,直到片段被破壞。而是通過getActivity()。getApplicationContext(); (或者更好的是,在你的適配器的構造函數中做:this.context = context.getApplicationContext();(這種方式你總是參考)

  3. 把代碼放在這裏真的很長(而且我必須回去工作!這種方式:

    • 將您的活動託管兩個(或更多)片段
    • 在你的片段(S)你執行修改相同的數據作爲另一個片段
    • 您需要通知的動作。大家誰有興趣,數據已被改變如此他們可以做任何需要的事情(更新UI,重新加載等)。

我將如何做到這一點

  1. 有一個包含已經被解析talks.xml列表中選擇一個 「DataController類」 級。任何人都可以這樣做:DataController.getInstance(context).getListOfTalks();
  2. DataController將檢查列表是否爲空並繼續創建/解析然後返回值。如果列表不爲空,那麼它將返回它。現在你的數據消費者不知道它來自哪裏,它總是來自同一個地方。
  3. 讓適配器從DataController中獲取數據,如#2所述。
  4. 既然數據位於中央存儲庫中,請讓數據控制器實施修改/保留數據的方法(即,如果您使用代碼應該在該控制器中的SQL)。
  5. 讓DataController實現一個Listener/Observer模式或類似的感興趣的團體可以訂閱並得到通知。
  6. 當fragment/onclick需要檢查一個盒子時,它會告訴DataController,DataController會保存這些新數據,然後繼續向其偵聽器發出通知。
  7. 每個片段在啓動時都會訂閱DataController(例如,在onStop()中刪除它自己)。
  8. 當片段收到此「通知」時,它們繼續告訴適配器更新數據。

聽起來很多,但你會獲得很多好東西。從視圖中分離數據,統一的地方,建立一個共同的通信模式等

這個DataController類的一些僞代碼將是...

public class DataController { 
    private static DataController sDataController; 
    private final Context mAppContext; 
    private final List<DataChangeListener> mListeners = new ArrayList<DataChangeListener>(); 
    private List<Talks> mData; 
    private DataController(final Context appContext) { 
     mAppContext = appContext; 
    } 
    public static DataController get(Context context) { 
     if (sDataController == null) { 
      if (context != null) { 
       sDataController = new DataController(context.getApplicationContext()); 
      } else { 
       sDataController = new DataController(YourAppClass.getInstance().getApplicationContext()); 
      } 
     } 
     return sDataController; 
    } 
    /** 
    * {@link DataChangeListener} listeners will be notified when certain requests have been made. 
    * 
    * @param listener - a valid DataChangeListener. If null, nothing is added. 
    */ 
    public void addDataChangeListener(DataChangeListener listener) { 
     if (listener != null && !mListeners.contains(listener)) { 
      mListeners.add(listener); 
     } 
    } 
    /** 
    * Remove a {@link DataChangeListener} from the list. 
    * 
    * @param listener - a valid DataChangeListener. If null, nothing is removed. 
    */ 
    public void addDataChangeListener(DataChangeListener listener) { 
     if (listener != null) { 
      mListeners.remove(listener); 
     } 
    } 

// INTERESTING METHODS YOU HAVE TO IMPLEMENT 

    public List<Talks> getData(){ 
     if (mData == null) { 
      parseData();// implement this 
     } 
     return mData; 
    } 
    public void checkBoxChanged(final somedatatype somedata) { 
     // pass the appropriate values you need and save them to your sql, update the list of talks 
     // talks should contain the value of the checkbox, add it to your Talks object if it's not there. 
     updateSQL(); 
     notifyDataChnged(); 
    } 
    public notifyDataChnged(){ 
     if (mListeners != null) { 
      for (DataChangeListener listener : mListeners) { 
       listener.onDataSetChanged(); 
      } 
     } 
    } 
} 

這是接口:

public interface DataChangeListener { 
    void onDataSetChanged(); 
} 

現在你的碎片會做類似的事情:

@Override 
    public void onResume() { 
     super.onResume(); 
     DataController.getInstance(context).addDataChangeListener(this); 
    } 
    @Override 
    public void onPause() { 
     super.onPause(); 
     DataController.getInstance(context).removeDataChangeListener(this); 
    } 

當然,他們實現接口...

public class PapersFragment extends Fragment implements DataChangeListener { 

和有義務方法...

@Override 
public void onDataSetChanged(){ 
// Data has changed, do something about it, like telling the adapter and doing anything you see fit. 
} 

我覺得這是一個很好的起點,這將導致你更好的建築設計。

祝你好運!

+0

哇,非常感謝你的這個! 我現在要使用你的建議,希望它能幫助我生成更好的代碼。 這個問題對我有幫助,但是如果我遇到其他問題,您是否允許我以後再回復您? –

+0

當然,如果您有特定的問題,通常會發布不同的問題。 :) –