无法同步过滤器
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);
}});
}
而且就像这样,我们可以顺序执行几个过滤器操作。
我已经实现了几个 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);
}});
}
而且就像这样,我们可以顺序执行几个过滤器操作。