Refreshing parent fragment on PopupWindow.dismiss

2019-05-23 07:22发布

问题:

I have a popupWindow that modifies a SQLight table that loads a spinner in the parent window. I would like to have the spinner in the parent window refreshed with the new values when I dismiss the PopupWindow. The code below shows my progress creating a listener that would detect the PopupWindow's dismissal. The listener that I have so far does not work. I think that I have missed something in structuring the listener. I've included the ShowPopup class as well as the fragment (Tab3Fragment) that is the parent to this window.

showPopup.java

public class showPopup extends PopupWindow{
Context m_context;
Button btnDismiss;
PopupWindow popup;
Tab3Fragment Tab3Fragment;
OnDismissListener listener;

public showPopup(Context context){
    super(context);
    m_context = context;//was commented out

    setContentView(LayoutInflater.from(context).inflate(R.layout.popup_layout, null));
    setHeight(LayoutParams.WRAP_CONTENT);
    setWidth(LayoutParams.WRAP_CONTENT);
}
public void init(View v){
    LayoutInflater inflater = (LayoutInflater)m_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View popUpView = inflater.inflate(R.layout.popup_layout, null, false);
    final PopupWindow popup = new PopupWindow(popUpView, 600, 400, true);  

    popup.setContentView(popUpView);
    popup.showAtLocation(v, Gravity.CENTER_HORIZONTAL, 0, 0);

    btnDismiss = (Button) popUpView.findViewById(R.id.btndismissxml);
    btnDismiss.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View anchor) {
            popup.dismiss();
        }
    });
}
@Override
public void setOnDismissListener(OnDismissListener listener){
    this.listener = listener;
  }  
}

Tab3Fragment.java

public class Tab3Fragment extends Fragment implements OnClickListener{
Context context;
Button btnPopup, btnSpinnerRefresh;
Spinner spinnerSpecies;
public static int iSpeciesPosition;
showPopup showPopup;
ArrayAdapter<String> arrayAdapterSpecies;
OnDismissListener dismissListener;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup containerGroup, Bundle savedInstanceState) {    
    View v = inflater.inflate(R.layout.tab3_fragment, containerGroup, false);    

    btnPopup = (Button)v.findViewById(R.id.btnPopupxml);
    btnPopup.setOnClickListener(this);

    btnSpinnerRefresh = (Button)v.findViewById(R.id.btnSpinnerRefreshxml);
    btnSpinnerRefresh.setOnClickListener(this);

    spinnerSpecies = (Spinner) v.findViewById(R.id.spinnerSpeciesxml);
    spinnerSpecies.setAdapter(arrayAdapterSpecies);

    if(savedInstanceState != null){
        iSpeciesPosition = savedInstanceState.getInt("speciesPosition_key");
        populateTab3Fragment(v);
    }else if(savedInstanceState == null){
        populateTab3Fragment(v);
    }
    return v;       
}
//@Override
public void onViewCreated(View v) {
    populateTab3Fragment(v);
    /******************************************************************************************************
    Can setOnDismissListener be used outside of showPopup class to indicate that showPopup has dismissed? 
    ******************************************************************************************************/
    showPopup popup = new showPopup(context);
    popup.setOnDismissListener(new OnDismissListener(){

        @Override
        public void onDismiss(){
            Toast.makeText(getActivity().getApplicationContext(), "onDismiss() works.", Toast.LENGTH_LONG).show();
            loadSpinnerData();
        }  
    });         
}
@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btnPopupxml:
        new showPopup(getActivity().getApplicationContext()).init(v);
        break;
    case R.id.btnSpinnerRefreshxml:
        loadSpinnerData();//temporary workaround to refresh spinner...
        break;
    }
}
/**
 * Function to load the spinner data from SQLite database
 * */
public void loadSpinnerData() {
    //omitted
}
public void populateTab3Fragment(View v){   
    loadSpinnerData();              
   }
}

回答1:

Never got to the point where I could refresh the parent window directly on the child PopupWindow dismiss. The final solution (workaround) was to use fragmentmanager replace() after an onTouch event from the spinner only when a static flag (iSpeciesRefresh) had been set that indicated a modified SQL spinner lookup table.

public class dataCapture extends Fragment implements OnClickListener {
String szSpecies;
static public int iSpeciesRefresh = 1;
Spinner spinnerSpecies;
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.data_capture, container, false);
...
    spinnerSpecies = (Spinner) v.findViewById(R.id.spinnerSpeciesxml);

    spinnerSpecies.setOnTouchListener(new View.OnTouchListener() {//refreshes fragment as needed...
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (iSpeciesRefresh == 1) {//this is application default
                //do nothing
            } else if (iSpeciesRefresh == 0) {//value is reset to "0" at SAVE, UPDATE, or DELETE in speciesPopupWindow.
                refreshDataCapture();
                iSpeciesRefresh = 1;
            }
            return false;
        }
    });
...
}    
public void refreshDataCapture() {
    Fragment currentFragment = (dataCapture) getFragmentManager().findFragmentByTag("data_capture");
    if (currentFragment == null) {
        currentFragment = new dataCapture();
    } else if (currentFragment != null) {
        getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        getFragmentManager().beginTransaction().replace(R.id.fragment_placeholder, new dataCapture(), "data_capture").addToBackStack(null).commit();       
    }
}


回答2:

In your onCreateView and onViewCreated methods, you do btnPopup.setOnClickListener(this);, but then in your showPopup class' init() method, you overwrite your fragment as the listener and instead assign a new anonymous listener. My guess is that you need to rework how you assign your listener and make sure you don't overwrite it like that.

P.S. For maintainability's sake (and the sanity of other developers who look at your code), it's convention to name classes with upper camel case and they should not contain verbs. Something like MyCustomPopup would be better.