2017-08-08 94 views
0

我有一個ListView連接到CustomAdapter。在Adapter類中,我有不同Views的偵聽器。當有新的變化,過來Android:從適配器獲取信息

currentItem.myListItemMethod() 

現在我不知道如何獲得這些信息反饋到保存的ListView的片段更新列表項的值。我試過

adapter.registerDataSetObserver 

在片段中,但它不會對適配器內的任何更改做出反應。僅適用於片段本身的更改(如單擊添加新項目的按鈕)。

另外我想知道如何獲得對Adapter類中最新的ArrayList的引用,所以我可以將它返回給Fragment。

我希望我的問題是可以理解的,我是編程新手。

編輯:

這裏我片段使用ListView

public class SettingsWindow extends Fragment { 

    private ArrayList<IncentiveItem> mIncentiveList; 

    private OnFragmentInteractionListener mListener; 

    ListView incentiveList; 

    IncentiveAdapter adapter; 

    public SettingsWindow() { 
     // Required empty public constructor 
    } 


    public static SettingsWindow newInstance(ArrayList<IncentiveItem> incentiveList) { 
     SettingsWindow fragment = new SettingsWindow(); 
     Bundle args = new Bundle(); 
     args.putSerializable("Incentive List", incentiveList); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if (getArguments() != null) { 
      mIncentiveList = (ArrayList<IncentiveItem>) getArguments().getSerializable("Incentive List"); 
     } 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     final View inf = inflater.inflate(R.layout.fragment_settings_window, container, false); 
     incentiveList = (ListView) inf.findViewById(R.id.incentive_list_xml); 

     adapter = new IncentiveAdapter(getActivity(), mIncentiveList); 

     incentiveList.setAdapter(adapter); 

     return inf; 
    } 



    // TODO: Rename method, update argument and hook method into UI event 
    public void onButtonPressed(Uri uri) { 
     if (mListener != null) { 
      mListener.onFragmentInteraction(uri); 
     } 
    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     if (context instanceof OnFragmentInteractionListener) { 
      mListener = (OnFragmentInteractionListener) context; 
     } else { 
      throw new RuntimeException(context.toString() 
        + " must implement OnFragmentInteractionListener"); 
     } 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mListener = null; 
    } 

    /** 
    * This interface must be implemented by activities that contain this 
    * fragment to allow an interaction in this fragment to be communicated 
    * to the activity and potentially other fragments contained in that 
    * activity. 
    * <p> 
    * See the Android Training lesson <a href= 
    * "http://developer.android.com/training/basics/fragments/communicating.html" 
    * >Communicating with Other Fragments</a> for more information. 
    */ 
    public interface OnFragmentInteractionListener { 
     // TODO: Update argument type and name 
     void onFragmentInteraction(Uri uri); 
    } 

    public void addIncentive() { 
     mIncentiveList.add(new IncentiveItem()); 
     adapter.notifyDataSetChanged(); 
    } 

} 

這是適配器

public class IncentiveAdapter extends ArrayAdapter<IncentiveItem> { 


    public IncentiveAdapter(Activity context, ArrayList<IncentiveItem> incentiveList) { 
     super(context, 0, incentiveList); 
    } 

    @NonNull 
    @Override 
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { 
     View listItemView = convertView; 
     if (listItemView == null) { 
      listItemView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false); 
     } 

     final IncentiveItem currentItem = getItem(position); 

     //We get references for the Views within the Incentive Item 
     final ImageView star = (ImageView) listItemView.findViewById(R.id.star_xml); 
     final EditText description = (EditText) listItemView.findViewById(R.id.incentive_text_xml); 
     SeekBar seekBar = (SeekBar) listItemView.findViewById(R.id.seekbar_xml); 
     final TextView percentage = (TextView) listItemView.findViewById(R.id.seekbar_percentage_xml); 

     star.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       if (currentItem.getActiveOrInactive() == false) { 
        currentItem.setActive(); 
        star.setImageResource(R.drawable.ic_star_active); 
       } else { 
        currentItem.setInActive(); 
        star.setImageResource(R.drawable.ic_star_inactive);; 
       } 
      } 
     }); 

     description.addTextChangedListener(new TextWatcher() { 
      @Override 
      public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 

      } 

      @Override 
      public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 
       currentItem.setText(description.getText().toString()); 
      } 

      @Override 
      public void afterTextChanged(Editable editable) { 

      } 
     }); 

     seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 
      @Override 
      public void onProgressChanged(SeekBar seekBar, int progress, boolean b) { 
       percentage.setText("" + progress + "%"); 
       currentItem.setProbabilityInPercent(progress); 
      } 

      @Override 
      public void onStartTrackingTouch(SeekBar seekBar) { 

      } 

      @Override 
      public void onStopTrackingTouch(SeekBar seekBar) { 

      } 
     }); 

     return listItemView; 
    } 

} 
+0

請張貼相關的適配器和片段代碼。 – Stuckzilla

+0

我真的不知道要發佈哪些部分要誠實。 –

+0

發佈整個文件絕不會出錯。重新編輯你不想看到的任何敏感內容。 – Stuckzilla

回答

1

您可以在適配器類中創建一個interface ,你可以在你的片段中實現該接口並將其設置爲適配器以便在適配器中發生任何更改時通知該片段。

此外,我想知道我怎麼能到適配器類中最先進的最新 ArrayList的一個參考,這樣我就可以將其退還給片段

爲此,我們可以使用默認的方法getItem(position)

所以適配器類的方法來創建這樣你可以得到完整的列表

public ArrayList<IncentiveItem> getItemValues() { 
    ArrayList<IncentiveItem> incentiveList = new ArrayList<IncentiveItem>(); 
    for (int i=0 ; i < getCount() ; i++){ 
     IncentiveItem incentiveItem = getItem(i); 
     incentiveList.add(incentiveItem); 
    } 
    return incentiveList; 
} 

EDITED 適配器類創建一個接口這樣

public interface OnAdapterItemActionListener { 
    public void onStarItemClicked(int position); 
    public void onSeekBarChage(int position, int progress); 
    //.. and you can add more method like this 
} 

在適配器中的片段,你應該增加這個接口在你的你的構造函數適配器,並認爲對象現在

public class IncentiveAdapter extends ArrayAdapter<IncentiveItem> { 

    private OnAdapterItemActionListener mListener; 
    public IncentiveAdapter(Activity context, ArrayList<IncentiveItem> incentiveList, OnAdapterItemActionListener listener) { 
     super(context, 0, incentiveList); 
     mListener = listener; 
    } 
} 

實現如下的接口

public class SettingsWindow extends Fragment implements OnAdapterItemActionListener{ 
    @Overrride 
    public void onStarItemClicked(int position) { 
     // You will get callback here when click in adapter 
    } 

    @Overrride 
    public void onSeekBarChage(int position, int progress) { 
     // You will get callback here when seekbar changed 
    } 
} 

而在創建適配器對象你應該在適當的時候送接口實現過,因爲在適配器構造函數中,我們期待的是,如此改變這一狀況,

adapter = new IncentiveAdapter(getActivity(), mIncentiveList, this); // this - Because we implemented in this class 

上面的代碼將完成接口設置,現在我們應該觸發界面如下圖所示,

當明星按鈕用戶點擊,我們應該觸發這個樣子,

star.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       //Your code here 
       if(mListener != null) { //Just for safety check 
        mListener.onStarItemClicked(position);// this will send the callback to your Fragment implementation 
       } 
      } 
     }); 
+0

謝謝,我會休息一下,然後我會試試看,也謝謝你解決我的問題佈局 –

+0

嘿,你能聯繫我一個教程,我到底該如何實現接口?我不知道它是如何工作的,我找不到合適的教程 –

+0

當我試圖弄清楚如何使用Fragments默認提供的onFragmentInteractionListener接口時,我遇到了同樣的問題,我注意到我可以從Fragment的調用Activitie的方法XML onclick屬性。是唯一可能的,因爲onFragmentInteraction接口,或者是可能的默認情況下? –