无法同步过滤器

Trouble synchronizing Filters

我已经实现了几个 Filter 类型,当我 select 它们在 AlertDialog (多选)中时它们工作正常,我保存这个 selection 以备将来使用,即如果我再次打开应用程序,但在这种情况下,它只适用于最后一个过滤器。

外观是这样的

selected 标准被很好地保存并且 selection in AlertDialog 立即反映过滤器按钮(作物年份...和作物类型)和点击这些按钮删除过滤器标准也反映出来,因此我在这里问,因为,当我 click/mark 一个选项和 AlertDialog 中的另一个选项是过滤后的数据可用于下一个 Filter/Unfilter 操作。

当我想用之前 selected 的标准(如前所述,它们是正确的)初始化元素时,异常发生了。

我试图在这两个过滤器之间引入延迟,以便第一个过滤器的过滤数据可用作第二个过滤器的输入,但我得到了相同的结果。

相关代码在这里

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);     
    setContentView(R.layout.farm_fields_list);
    // Get SharedPreferences
    session = new SessionManager(getApplicationContext()); 


    selected = getSelectedCriteria();

    ...



    // Retrieve Session
     session                 = new SessionManager(getApplicationContext()); 
     Log.i("TAG", "FarmListActivity::onCreate:: 1");
    // Get the Parameter
    Intent intent            = getIntent();

    Bundle bundle            = intent.getExtras();

    if ( bundle != null) {
        farms                = (ArrayList<Object>)bundle.get(Constants.FARMS);      
    }

    farm_field_exp_list_view.setDividerHeight(2);
    farm_field_exp_list_view.setGroupIndicator(null);
    farm_field_exp_list_view.setClickable(true);


    /** Adapter initialisieren **/
    myFarmAdapter = new MyFarmAdapter(FarmListActivity.this, farms, mapView);

    farm_field_exp_list_view.setAdapter(myFarmAdapter);     



    /** Filter Buttons initialisieren **/
    initializeFilterButton(crop_type_button, Constants._CROP_TYPE_MAIS_CRITERIUM, 0); // <- At this point
    initializeFilterButton(crop_year_button, Constants._CROP_YEAR_2015_CRITERIUM, 1);


    /**         **/     

    // Button
    show_fields_button = (Button) findViewById(R.id.show_map_btn);
    show_fields_button.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {

            // We'll pass as parameter an ArrayList of field_guids, whose fields will be shown
            ArrayList<String> selectedFields = myFarmAdapter.getSelectedFields();
            Intent intent = new Intent();
            intent.putExtra(Constants.SELECTED_FIELDS, selectedFields);

            // --------------------------
            activity.setResult(Activity.RESULT_OK, intent);
            activity.finish();              

        }

    });
    //

}

private void initializeFilterButton(final Button filter_button, final String filter_criterium, final int pos) {

    // First we check whether buttons can be initialized via SharedPreferences - selected


    if ( selected != null ){
        filter_button.setVisibility(selected[pos] ? View.VISIBLE : View.GONE);
        if (selected[pos]) {
            myFarmAdapter.getFilter().filter(filter_criterium);
        }

    }

    // I we click, then we remove the filter
    filter_button.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {                
            // Unset Filter Type F1 is the same like filter the original Data with the other Filters (if present) 

            myFarmAdapter.getFilter().filter(Constants._REMOVE_CRITERIUM+filter_criterium);
            filter_button.setVisibility(View.GONE);
            selected[pos] = false;
            settings.put(Constants._SELECTED_CRITERIA, Arrays.toString(selected));

            session.createOrUpdateSettings(settings);


    }});    

}

@Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        // action with ID action_filter was selected
        case R.id.action_filter: 
            Dialogs.showFilterDialog(this, session, myFarmAdapter, appliedFilterTV, crop_year_button, crop_type_button);
            //Toast.makeText(this, "Filter selected", Toast.LENGTH_LONG).show();
        break;
        default:
        break;
    }

    return true;
  }

如果我的相关部分 Class Dialogs

    public static void showFilterDialog(final FarmListActivity farmListActivity, final SessionManager session, final MyFarmAdapter myFarmAdapter, 
                                        final TextView tView, final Button crop_year_button, final Button crop_type_name_button) {

        settings                              = session.getSettings();

        String[] filter_menu = farmListActivity.getResources().getStringArray(R.array.filter_menu);

        selected = new boolean[filter_menu.length];
        if ( settings.containsKey(Constants._SELECTED_CRITERIA)) {
            selected = parseBooleanStringToBooleanArray(settings.get(Constants._SELECTED_CRITERIA));

        } else {

            Arrays.fill(selected, false);
        }

        yes                                    = false;

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(farmListActivity);     
        // set title
        alertDialogBuilder.setTitle(R.string.title_choice_filter);


        alertDialogBuilder.setMultiChoiceItems(R.array.filter_menu, selected, new OnMultiChoiceClickListener(){

            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked ) {
                // TODO Auto-generated method stub
                int visibility          = 0;
                String[] filters        = farmListActivity.getResources().getStringArray(R.array.filter_menu);
                int filters_size        = filters.length;

                String filter_criterium = "";


                selected[which]  = isChecked;

                filter_criterium = filters[which];

                // If checked, remove selected criterium
                filter_criterium = isChecked ? filter_criterium : Constants._REMOVE_CRITERIUM + filter_criterium;

                // Filter 
                myFarmAdapter.getFilter().filter(filter_criterium);

                // Here we save the selected criterium
                settings.put(Constants._SELECTED_CRITERIA, Arrays.toString(selected));

                // Here we update button visibility
                visibility = isChecked ? View.VISIBLE : View.GONE;

                // Activate the Filter Buttons
                if ( filter_criterium.equalsIgnoreCase(Constants._CROP_YEAR_2015_CRITERIUM)) {
                    crop_year_button.setVisibility(visibility);
                }

                if ( filter_criterium.equalsIgnoreCase(Constants._CROP_TYPE_MAIS_CRITERIUM)) {
                    crop_type_name_button.setVisibility(visibility);                        
                }       


                settings.put(Constants._SELECTED_CRITERIA, Arrays.toString(selected));

                session.createOrUpdateSettings(settings);

            }});
        alertDialogBuilder.setCancelable(false);
        alertDialogBuilder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub

                dialog.dismiss();
            }
        });

        // create alert dialog
        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        for ( int i = 0; i < selected.length; i++)
            alertDialog.getListView().setItemChecked(i, selected[i]);
        // show it
        alertDialog.show();         
    }

最后是我的日志

02-17 11:30:49.694: I/TAG(10211): FarmListActivity::initializeFilterButton::BEGIN filter_criterium: Year(Current Year: 2015) pos: 1 selected: [true, true]
02-17 11:30:49.694: I/TAG(10211): FarmListActivity::initializeFilterButton::if (selected[pos]) {
02-17 11:30:49.696: I/TAG(10211): MyFarmAdapter::getFilter:: fieldFilter: com.nutiteq.advancedmap.MyFarmAdapter$FieldFilter@ebe6c48
02-17 11:30:49.699: I/TAG(10211): FieldFilter::performFiltering:: constraint: [Year(Current Year: 2015)] constraintsList: []
02-17 11:30:49.699: I/TAG(10211): FarmListActivity::initializeFilterButton::END filter_criterium: Year(Current Year: 2015) pos: 1 selected: [true, true]
02-17 11:30:49.699: I/TAG(10211): FieldFilter::performFiltering:: constraint: [Year(Current Year: 2015)] #fields of filteredItems: 35 #fields of parentItems: 35
02-17 11:30:49.699: I/TAG(10211): FarmListActivity::initializeFilterButton::BEGIN filter_criterium: Crop(Current Crop: Mais) pos: 0 selected: [true, true]
02-17 11:30:49.699: I/TAG(10211): FarmListActivity::initializeFilterButton::if (selected[pos]) {
02-17 11:30:49.699: I/TAG(10211): MyFarmAdapter::getFilter:: fieldFilter: com.nutiteq.advancedmap.MyFarmAdapter$FieldFilter@ebe6c48
02-17 11:30:49.699: I/TAG(10211): FarmListActivity::initializeFilterButton::END filter_criterium: Crop(Current Crop: Mais) pos: 0 selected: [true, true]
02-17 11:30:49.699: I/TAG(10211): MyFarmAdapter::FieldFilter::filterByCropYear:: crop_year: 2015
02-17 11:30:49.700: I/TAG(10211): MyFarmAdapter::FieldFilter::filterByCropYear::fields.size: 35
02-17 11:30:49.700: I/TAG(10211): FieldFilter::performFiltering:: AFTER filtering:: constraint: Year(Current Year: 2015) #fields of filteredItems: 35 #fields of parentItems: 35
02-17 11:30:49.700: I/TAG(10211): FieldFilter::performFiltering:: constraint: [Crop(Current Crop: Mais)] constraintsList: [Year(Current Year: 2015)]
02-17 11:30:49.700: I/TAG(10211): FieldFilter::performFiltering:: constraint: [Crop(Current Crop: Mais)] #fields of filteredItems: 35 #fields of parentItems: 35
02-17 11:30:49.704: I/TAG(10211): MyFarmAdapter::FieldFilter::filterByCropTypeName::fields.size: 35
02-17 11:30:49.704: I/TAG(10211): FieldFilter::performFiltering:: AFTER filtering:: constraint: Crop(Current Crop: Mais) #fields of filteredItems: 35 #fields of parentItems: 35
02-17 11:30:49.771: I/TAG(10211): FieldFilter::publishResults:: constraint: Year(Current Year: 2015) #fields of filteredItems: 11 #fields of parentItems: 35
02-17 11:30:49.772: I/TAG(10211): FieldFilter::publishResults:: constraint: Crop(Current Crop: Mais) #fields of filteredItems: 10 #fields of parentItems: 35

正如您在日志文件中看到的那样,publishResults 方法设置数据可用的时间太晚了,我不知道如何在没有委托事件的情况下解决问题,必须有一个更简单的解决方案。

AlertDialog的情况下,我可以记录它,正确的顺序如下

1. performFiltering of first Filter
2. publishResults of first Filter
3. performFiltering of second Filter
4. publishResults of second Filter

我可以解决它,就像我对@Luksprog 说的那样,我在 Activity 中实现了 FilterListener 接口的方法,在这种情况下 public void onFilterComplete(int count) 如下

@Override
public void onFilterComplete(int count) {

    if ( ! isTrue(initialisedButtons) ) 
        initializeFilterButton(crop_year_button, Constants._CROP_YEAR_2015_CRITERIUM, 1);

}

private boolean isTrue(boolean[] initialisedButtons) {
    // TODO Auto-generated method stub
    boolean result = true;

    if ( initialisedButtons != null && initialisedButtons.length>0 ) {
        for ( int i = 0; i<initialisedButtons.length && result; i++)
            result = result && initialisedButtons[i];
    } else
        result = false;

    return result;
}

我在onFilterComplete方法中插入了行

initializeFilterButton(crop_year_button, Constants._CROP_YEAR_2015_CRITERIUM, 1);

并像这样修改initializeFilterButton

private void initializeFilterButton(final Button filter_button, final String filter_criterium, final int pos) {

    // First we check whether buttons can be initialized via SharedPreferences - selected


    if ( selected != null ){
        filter_button.setVisibility(selected[pos] ? View.VISIBLE : View.GONE);
        if (selected[pos]) {

            myFarmAdapter.getFilter().filter(filter_criterium, this);           
        } else {
            // Neccessary if the filter is disabled in order to fire FilterListener onFilterComplete. That's a NO Filter Operation
            myFarmAdapter.getFilter().filter("", this);         
        }
        // To ensure, we initialize this button.
        initialisedButtons[pos] = true;
    }


    filter_button.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {                
            // Unset Filter Type F1 is the same like filter the original Data with the other Filters (if present) 
        myFarmAdapter.getFilter().filter(Constants._REMOVE_CRITERIUM+filter_criterium);
            filter_button.setVisibility(View.GONE);
            selected[pos] = false;
            settings.put(Constants._SELECTED_CRITERIA, Arrays.toString(selected));              
            session.createOrUpdateSettings(settings);
    }});    
}

而且就像这样,我们可以顺序执行几个过滤器操作。