瀏覽代碼

[검색][New] 하위 태그 있는 항목 세부 설정

hyodong.min 7 年之前
父節點
當前提交
2db291e698

+ 20 - 7
app/src/main/java/kr/co/zumo/app/lifeplus/view/SingleSelector.java

@@ -63,19 +63,32 @@ public class SingleSelector {
     // 리스트에 속한 박스라면 다른 박스를 해제 시킨다.
     if (boxes.indexOf(box) > -1) {
       List<Checkable> list = new ArrayList<>();
-      if (box.isChecked()) {
-        for (Checkable checkable : boxes) {
-          if (box != checkable) {
-            checkable.setChecked(false);
-            list.add(checkable);
-          }
+      for (Checkable checkable : boxes) {
+        if (box != checkable) {
+          list.add(checkable);
         }
       }
-
       this.listener.onCheckChanged(box, list);
     }
   }
 
+  /**
+   * 전달 된 객체를 제외한 나머지만 uncheck
+   *
+   * @param box
+   */
+  public void uncheck(Checkable box) {
+    if (boxes.indexOf(box) > -1) {
+      List<Checkable> list = new ArrayList<>();
+      for (Checkable checkable : boxes) {
+        if (box != checkable) {
+          list.add(checkable);
+        }
+      }
+      this.listener.onCheckChanged(null, list);
+    }
+  }
+
   /**
    * 그룹에 속한 box 인지 확인
    *

+ 11 - 7
app/src/main/java/kr/co/zumo/app/lifeplus/view/dialog/ISearchFilterListener.java

@@ -3,8 +3,6 @@
  */
 package kr.co.zumo.app.lifeplus.view.dialog;
 
-import java.util.List;
-
 import kr.co.zumo.app.lifeplus.bean.api.SearchFilterBean;
 
 /**
@@ -20,19 +18,25 @@ import kr.co.zumo.app.lifeplus.bean.api.SearchFilterBean;
 public interface ISearchFilterListener<T extends IDialogBase> extends ICustomDialogListener<T> {
 
   /**
-   * 개별 필터 선택 시
+   * 필터 초기화
    *
    * @param dialog
-   * @param pickedList
    */
-  void onFilterChanged(T dialog, List<SearchFilterBean> pickedList);
+  void onFilterReset(T dialog);
+
+  /**
+   * 개별 필터 선택 시
+   *  @param dialog
+   *
+   */
+  void onFilterChanged(T dialog);
 
   /**
    * 필터 선택 결과
    * @param dialog
-   * @param pickedList
+   *
    */
-  void onFilterResult(T dialog, List<SearchFilterBean> pickedList);
+  void onFilterResult(T dialog);
 
   /**
    * 필터 세부 정보 요청 시

+ 45 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/view/dialog/SearchFilterCheckDriver.java

@@ -0,0 +1,45 @@
+/*
+ * COPYRIGHT (c) 2018 All rights reserved by HANWHA LIFE.
+ */
+package kr.co.zumo.app.lifeplus.view.dialog;
+
+import android.widget.Checkable;
+
+import kr.co.zumo.app.lifeplus.bean.api.SearchFilterBean;
+
+/**
+ * SearchFilterCheckDriver
+ * <pre>
+ * </pre>
+ *
+ * @author 민효동
+ * @version 1.0
+ * @history 민효동   [2019. 1. 24.]   [최초 작성]
+ * @since 2019. 1. 24.
+ */
+public class SearchFilterCheckDriver implements Checkable {
+
+  protected Checkable checkbox;
+  protected SearchFilterBean searchFilterBean;
+
+  public SearchFilterCheckDriver(Checkable checkbox, SearchFilterBean searchFilterBean) {
+    this.checkbox = checkbox;
+    this.searchFilterBean = searchFilterBean;
+  }
+
+  @Override
+  public void setChecked(boolean checked) {
+    checkbox.setChecked(checked);
+    searchFilterBean.setSelected(checked);
+  }
+
+  @Override
+  public boolean isChecked() {
+    return searchFilterBean.isSelected();
+  }
+
+  @Override
+  public void toggle() {
+    setChecked(!isChecked());
+  }
+}

+ 27 - 21
app/src/main/java/kr/co/zumo/app/lifeplus/view/dialog/SearchFilterDetailDialog.java

@@ -101,9 +101,12 @@ public class SearchFilterDetailDialog extends DialogBase<ISearchFilterListener<S
     });
   }
 
+  /**
+   * exit point
+   */
   private void applyFilter() {
     if (null != getCustomListener()) {
-      getCustomListener().onFilterResult(SearchFilterDetailDialog.this, null);
+      getCustomListener().onFilterResult(SearchFilterDetailDialog.this);
     }
   }
 
@@ -119,9 +122,11 @@ public class SearchFilterDetailDialog extends DialogBase<ISearchFilterListener<S
 
     // 하나만 선택 할 수 있도록
     SingleSelector selector = new SingleSelector((checked, unchecked) -> {
-      setSelectedList(checked);
+      if (null != checked) {
+        setSelected(checked, true);
+      }
       for (Checkable checkable : unchecked) {
-        setSelectedList(checkable);
+        setSelected(checkable, false);
       }
     });
 
@@ -142,9 +147,10 @@ public class SearchFilterDetailDialog extends DialogBase<ISearchFilterListener<S
         checkBoxAll.setText(R.string.search_filter_all);
 
         filterMap.put(checkBoxAll, tagBean);
+
         if (isMultiSelection) {
           checkBoxAll.setOnClickListener(v -> {
-            setSelectedList((Checkable) v);
+            setSelected((Checkable) v, true);
           });
         }
         else {
@@ -155,7 +161,7 @@ public class SearchFilterDetailDialog extends DialogBase<ISearchFilterListener<S
               selector.check((Checkable) v);
             }
             else {
-              setSelectedList((Checkable) v);
+              setSelected((Checkable) v, true);
             }
           });
         }
@@ -188,18 +194,24 @@ public class SearchFilterDetailDialog extends DialogBase<ISearchFilterListener<S
 
         if (isMultiSelection) {
           checkBox.setOnClickListener(v -> {
-            setSelectedList((Checkable) v);
+            setSelected((Checkable) v, true);
           });
         }
         else {
           selector.addChildBox(checkBox);
           checkBox.setOnClickListener(v -> {
-            if (selector.contains((Checkable) v)) {
-              // 셀렉터에 포함되있으면 셀렉터에서 처리
-              selector.check((Checkable) v);
+            Checkable cb = (Checkable) v;
+            if (selector.contains(cb)) {
+              if (cb.isChecked()) {
+                // 셀렉터에 포함되있으면 셀렉터에서 처리
+                selector.check(cb);
+              }
+              else {
+                setSelected(cb, false);
+              }
             }
             else {
-              setSelectedList((Checkable) v);
+              setSelected(cb, cb.isChecked());
             }
           });
         }
@@ -213,22 +225,16 @@ public class SearchFilterDetailDialog extends DialogBase<ISearchFilterListener<S
       }
     }
 
-    // 12dp bottom space
+    // bottom space
     View space = new Space(getContext());
-    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ResourceUtil.dpToPx(12));
+    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ResourceUtil.dpToPx(22));
     container.addView(space, layoutParams);
   }
 
-  private void setSelectedList(Checkable checkBox) {
+  private void setSelected(Checkable checkBox, boolean isCheck) {
     FilterTagBean tagBean = filterMap.get(checkBox);
-    tagBean.setSelected(checkBox.isChecked());
-  }
-
-  private void reset() {
-    ViewGroup container = getView().findViewById(R.id.layout_container);
-    container.removeAllViews();
-
-    init();
+    checkBox.setChecked(isCheck);
+    tagBean.setSelected(isCheck);
   }
 
   /**

+ 60 - 45
app/src/main/java/kr/co/zumo/app/lifeplus/view/dialog/SearchFilterDialog.java

@@ -110,7 +110,7 @@ public class SearchFilterDialog extends DialogBase<ISearchFilterListener<SearchF
 
     contentsCountTextView.setOnClickListener(v -> {
       if (null != getCustomListener()) {
-        getCustomListener().onFilterResult(SearchFilterDialog.this, null);
+        getCustomListener().onFilterResult(SearchFilterDialog.this);
       }
     });
   }
@@ -154,50 +154,61 @@ public class SearchFilterDialog extends DialogBase<ISearchFilterListener<SearchF
     }
   }
 
-  private void showDialogDetail(SearchFilterSection section, SearchFilterBean filterBean) {
-    new DialogBuilder<SearchFilterDetailDialog, ISearchFilterListener>(getFragmentManager(), DialogID.SEARCH_FILTER_DETAIL)
-      .listener(new ISearchFilterListener<SearchFilterDetailDialog>() {
-        @Override
-        public void onDialogResult(SearchFilterDetailDialog dialog, Event event) {
-          // nothing
-        }
+  SearchFilterDetailDialog detailDialog;
 
-        @Override
-        public void onDialogCanceled(SearchFilterDetailDialog dialog) {
-          dialog.dispose();
-        }
-
-        @Override
-        public void onFilterChanged(SearchFilterDetailDialog dialog, List<SearchFilterBean> pickedList) {
-          // nothing
-        }
-
-        @Override
-        public void onFilterDetail(SearchFilterDetailDialog dialog, SearchFilterBean searchFilterBean) {
-          // nothing
-        }
-
-        @Override
-        public void onFilterResult(SearchFilterDetailDialog dialog, List<SearchFilterBean> pickedList) {
-          dialog.dispose();
-
-          section.onDetailResult(filterBean);
-
-          applyContentsNumber();
-        }
-      })
-      .attribute(dialog -> {
-        String title;
-        if (SearchFilterBean.FILTER_TYPE_AREA.equals(filterBean.getFilterType())) {
-          title = ResourceUtil.getString(R.string.search_filter_detail_title_area, filterBean.getFilterName());
-        }
-        else {
-          title = ResourceUtil.getString(R.string.search_filter_detail_title, filterBean.getFilterName());
-        }
-
-        dialog.setFilterDetail(filterBean.getTagBeans(), title, LifeplusData.isTrue(filterBean.getMultiSelection()));
-      })
-      .show();
+  private void showDialogDetail(SearchFilterSection section, SearchFilterBean filterBean) {
+    if (null == detailDialog) {
+      detailDialog = new DialogBuilder<SearchFilterDetailDialog, ISearchFilterListener>(getFragmentManager(), DialogID.SEARCH_FILTER_DETAIL)
+        .listener(new ISearchFilterListener<SearchFilterDetailDialog>() {
+          @Override
+          public void onDialogResult(SearchFilterDetailDialog dialog, Event event) {
+            // nothing
+          }
+
+          @Override
+          public void onDialogCanceled(SearchFilterDetailDialog dialog) {
+            dialog.dispose();
+            detailDialog = null;
+          }
+
+          @Override
+          public void onFilterReset(SearchFilterDetailDialog dialog) {
+            // nothing
+          }
+
+          @Override
+          public void onFilterChanged(SearchFilterDetailDialog dialog) {
+            // nothing
+          }
+
+          @Override
+          public void onFilterDetail(SearchFilterDetailDialog dialog, SearchFilterBean searchFilterBean) {
+            // nothing
+          }
+
+          @Override
+          public void onFilterResult(SearchFilterDetailDialog dialog) {
+            dialog.dispose();
+            detailDialog = null;
+
+            section.onDetailResult(filterBean);
+
+            applyContentsNumber();
+          }
+        })
+        .attribute(dialog -> {
+          String title;
+          if (SearchFilterBean.FILTER_TYPE_AREA.equals(filterBean.getFilterType())) {
+            title = ResourceUtil.getString(R.string.search_filter_detail_title_area, filterBean.getFilterName());
+          }
+          else {
+            title = ResourceUtil.getString(R.string.search_filter_detail_title, filterBean.getFilterName());
+          }
+
+          dialog.setFilterDetail(filterBean.getTagBeans(), title, LifeplusData.isTrue(filterBean.getMultiSelection()));
+        })
+        .show();
+    }
   }
 
   /**
@@ -205,7 +216,7 @@ public class SearchFilterDialog extends DialogBase<ISearchFilterListener<SearchF
    */
   private void applyContentsNumber() {
     if (null != getCustomListener()) {
-      getCustomListener().onFilterChanged(this, null);
+      getCustomListener().onFilterChanged(this);
     }
   }
 
@@ -214,6 +225,10 @@ public class SearchFilterDialog extends DialogBase<ISearchFilterListener<SearchF
     ViewGroup container = getView().findViewById(R.id.layout_container);
     container.removeAllViews();
 
+    if (null != getCustomListener()) {
+      getCustomListener().onFilterReset(this);
+    }
+
     init();
   }
 

+ 77 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/view/dialog/SearchFilterParentCheckDriver.java

@@ -0,0 +1,77 @@
+/*
+ * COPYRIGHT (c) 2018 All rights reserved by HANWHA LIFE.
+ */
+package kr.co.zumo.app.lifeplus.view.dialog;
+
+import android.widget.Checkable;
+
+import kr.co.zumo.app.lifeplus.bean.api.FilterTagBean;
+import kr.co.zumo.app.lifeplus.bean.api.SearchFilterBean;
+
+/**
+ * SearchFilterParentCheckDriver
+ * <pre>
+ * </pre>
+ *
+ * @author 민효동
+ * @version 1.0
+ * @history 민효동   [2019. 1. 24.]   [최초 작성]
+ * @since 2019. 1. 24.
+ */
+public class SearchFilterParentCheckDriver extends SearchFilterCheckDriver {
+
+  public SearchFilterParentCheckDriver(Checkable checkbox, SearchFilterBean searchFilterBean) {
+    super(checkbox, searchFilterBean);
+  }
+
+  /**
+   * 파라메터에 따라서 자식들을 검색하여 반영
+   *
+   * @param checked true -> 자식들의 상황에 따라서 결정, false -> 비활성, 자식들도 모두 비활성
+   */
+  @Override
+  public void setChecked(boolean checked) {
+    // 자식들이 있는 버튼은
+    // -> 체크: 하위 항목 선택을 위한 다이얼로그 열어줌, 다이얼로그 닫힐 때 하위 선택 여부에 따라서 체크 유무 결정
+    // -> 언체크: 자신과 하위 항목 모두 언체크
+
+    // 우선 비활성
+    checkbox.setChecked(false);
+
+    if (checked) {
+      // 자식 중 하나라도 활성일 때만 체크
+      boolean canCheck = false;
+      if (SearchFilterBean.hasChildValue(searchFilterBean)) {
+        for (FilterTagBean tagBean : searchFilterBean.getTagBeans()) {
+          if (tagBean.isSelected() == true) {
+            canCheck = true;
+            break;
+          }
+        }
+      }
+
+      checkbox.setChecked(canCheck);
+      searchFilterBean.setSelected(canCheck);
+
+    }
+    else {
+      // 자식이 있다면 모두 비활성
+      searchFilterBean.setSelected(false);
+      if (SearchFilterBean.hasChildValue(searchFilterBean)) {
+        for (FilterTagBean tagBean : searchFilterBean.getTagBeans()) {
+          tagBean.setSelected(false);
+        }
+      }
+    }
+  }
+
+  @Override
+  public boolean isChecked() {
+    return false;
+  }
+
+  @Override
+  public void toggle() {
+
+  }
+}

+ 39 - 43
app/src/main/java/kr/co/zumo/app/lifeplus/view/dialog/SearchFilterSection.java

@@ -18,7 +18,6 @@ import java.util.Map;
 
 import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.bean.SearchFilterSectionBean;
-import kr.co.zumo.app.lifeplus.bean.api.FilterTagBean;
 import kr.co.zumo.app.lifeplus.bean.api.LifeplusData;
 import kr.co.zumo.app.lifeplus.bean.api.SearchFilterBean;
 import kr.co.zumo.app.lifeplus.util.ResourceUtil;
@@ -55,15 +54,6 @@ public class SearchFilterSection {
     init(container.getContext());
   }
 
-  /**
-   * 외부에서 전달되는 selectedList 에는 세부 (지역/핫플레이스 등)이 포함되므로 이를 제외하고 속성만 사용한다.
-   * - 디테일 속성은 map 에 저정
-   * - 디테일인지 여부는 level = FILTER_LEVEL_DETAIL
-   */
-  private void parseSelectedList() {
-    List<SearchFilterBean> filterBeans = sectionBean.getFilterBeans();
-  }
-
   private void init(Context context) {
 
     filterMap = new HashMap<>();
@@ -79,11 +69,13 @@ public class SearchFilterSection {
     if (null != filterBeans && filterBeans.size() > 0) {
 
       SingleSelector selector = new SingleSelector((checked, unchecked) -> {
-        setSelected(checked);
+        if (null != checked) {
+          setSelected(checked, true);
+        }
+
         for (Checkable checkable : unchecked) {
-          setSelected(checkable);
+          setSelected(checkable, false);
         }
-        requestContentsCount();
       });
 
       int len = filterBeans.size();
@@ -97,21 +89,24 @@ public class SearchFilterSection {
         layoutParams.bottomMargin = ResourceUtil.dpToPx(4);
 
 
+        SearchFilterCheckDriver driver;
         CustomCheckBox checkBox;
         if (SearchFilterBean.hasChild(filterBean)) {
           // 세부 설정 필요
           checkBox = new CustomSquareArrowCheckBox(context);
-          // touch event
+
+          driver = new SearchFilterParentCheckDriver(checkBox, filterBean);
+
           checkBox.setOnClickListener(v -> {
-            if (selector.contains((Checkable) v)) {
-              // 셀렉터에 포함되있으면 셀렉터에서 처리
-              selector.check((Checkable) v);
-            }
-            else {
-              setSelected((Checkable) v);
-            }
 
-            // 세부 팝업 표시
+            // 우선 체크한 상태로 표시
+            checkBox.setChecked(true);
+
+            if (selector.contains(driver)) {
+              // 자신을 제외한 나머지는 언체크
+              selector.uncheck(driver);
+            }
+            // 세부 팝업 표시 -> 체크 여부는 팝업 후 처리 onDetailResult()
             requestDetail(filterBean);
           });
         }
@@ -124,25 +119,33 @@ public class SearchFilterSection {
             // 체크 박스
             checkBox = new CustomSquareCheckBox(context);
           }
+
+          driver = new SearchFilterCheckDriver(checkBox, filterBean);
+
           checkBox.setOnClickListener(v -> {
-            if (selector.contains((Checkable) v)) {
-              // 셀렉터에 포함되있으면 셀렉터에서 처리
-              selector.check((Checkable) v);
+            Checkable cb = (Checkable) v;
+            if (selector.contains(driver)) {
+              if (cb.isChecked()) {
+                // 셀렉터에 포함되있으면 셀렉터에서 처리
+                selector.check(driver);
+              }
+              else {
+                setSelected(driver, false);
+              }
             }
             else {
-              setSelected((Checkable) v);
-              requestContentsCount();
+              setSelected(driver, cb.isChecked());
             }
-
+            requestContentsCount();
           });
         }
 
         // 하나만 선택 가능.
         if (LifeplusData.isTrue(filterBean.getMultiSelection()) == false) {
-          selector.addChildBox(checkBox);
+          selector.addChildBox(driver);
         }
 
-        filterMap.put(checkBox, filterBean);
+        filterMap.put(driver, filterBean);
 
         checkBox.setText(filterBean.getFilterName());
 
@@ -172,23 +175,16 @@ public class SearchFilterSection {
     // 1개 이상 선택됐다면 해당 체크박스를 체크해준다. 0개는 선택 해제
     for (Checkable checkable : filterMap.keySet()) {
       if (filterBean.getFilterNo().equals(filterMap.get(checkable).getFilterNo())) {
-        checkable.setChecked(filterBean.isSelected());
+        // checkable must be SearchFilterParentCheckDriver.
+        // true 로 전달하면 자식들의 상황을 고려하여 처리된다.
+        checkable.setChecked(true);
         break;
       }
     }
   }
-  
-  private void setSelected(Checkable checkBox) {
-    SearchFilterBean filterBean = filterMap.get(checkBox);
-    boolean isChecked = checkBox.isChecked();
-    filterBean.setSelected(isChecked);
-
-    // 자식이 있다면 모두 비활성
-    if(SearchFilterBean.hasChildValue(filterBean)) {
-      for (FilterTagBean tagBean : filterBean.getTagBeans()) {
-        tagBean.setSelected(isChecked);
-      }
-    }
+
+  private void setSelected(Checkable checkable, boolean isCheck) {
+    checkable.setChecked(isCheck);
   }
 
   public View getView() {

+ 43 - 43
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/search/SearchResultModel.java

@@ -77,6 +77,7 @@ public class SearchResultModel extends Model {
   private List<CategoryCheckBean> categoryCheckBeans;
 
   private int selectedCategoryIndex = 0;
+  private boolean isFilterApplied = false;
 
   public SearchResultModel() {
     ContentsFlagHelper.getInstance().registerChangedObserver(hashCode);
@@ -448,7 +449,11 @@ public class SearchResultModel extends Model {
   }
 
   public boolean hasResult() {
-    return getTagResultBeans().size() > 0 || (null != appliedSearchFilterBeans && appliedSearchFilterBeans.size() > 0);
+    return getTagResultBeans().size() > 0;
+  }
+
+  public boolean isFilterApplied() {
+    return isFilterApplied;
   }
 
   private SearchFilterBean getSearchFilterBean(@StringRes int nameId, String filterNo) {
@@ -462,11 +467,10 @@ public class SearchResultModel extends Model {
   }
 
   public void loadFilter() {
-    // todo buffer 구성 필요?
-//    if (null != searchFilterSectionBeans) {
-//      onResult(new Event.Builder(Event.SUCCESS).index(Event.LOADED_FILTER).build());
-//      return;
-//    }
+    if (null != searchFilterSectionBeans) {
+      onResult(new Event.Builder(Event.SUCCESS).index(Event.LOADED_FILTER).build());
+      return;
+    }
 
     disposableFilter = new APISearchFilterModule().call(new RequestBean(), new APIModuleSimpleListener<SearchFilterResultBean>(waiterCaller) {
       @Override
@@ -538,33 +542,13 @@ public class SearchResultModel extends Model {
   }
 
   private SearchResultBean filterSearchResultBean;
-  private List<SearchFilterBean> searchFilterBeans;
   private List<SearchFilterBean> appliedSearchFilterBeans;
   private List<SearchFilterSectionBean> searchFilterSectionBeans;
 
-  /**
-   * 리스트에 반영된 필터 id 리스트 반환
-   *
-   * @return
-   */
-  public List<SearchFilterBean> getAppliedSearchFilterBeans() {
-    return appliedSearchFilterBeans;
-  }
-
   public final List<SearchFilterSectionBean> getFilterList() {
     return searchFilterSectionBeans;
   }
 
-  /**
-   * 필터 설정 - 아직 실제 리스트에 반영하기 전 데이터
-   *
-   * @param filterIds
-   */
-  public void setFilter(List<SearchFilterBean> filterIds) {
-    // 선택 리스트가 없이 object 참조를 이용
-//    searchFilterBeans = filterIds;
-  }
-
   public void loadFilteringContents(IWaiterCallable waiterCallable, IEventListener listener) {
     Log.w("APP# SearchResultModel | loadFilteringContents", "|" + " -------------------------- ");
 
@@ -579,6 +563,8 @@ public class SearchResultModel extends Model {
       requestBean.setCategoryNumber(categoryCheckBean.getCategoryNumber());
     }
 
+    isFilterApplied = false;
+
     // 필터 적용
     if (applyFilter(requestBean) == false) {
       filterSearchResultBean = null;
@@ -597,6 +583,7 @@ public class SearchResultModel extends Model {
       public void onApiSuccess(SearchResultBean resultBean) {
         filterSearchResultBean = resultBean;
         if (null != filterSearchResultBean) {
+          isFilterApplied = true;
           int count = filterSearchResultBean.getListCount();
           if (null == filterSearchResultBean.getTagBeans() || filterSearchResultBean.getTagBeans().size() == 0) {
             count = 0;
@@ -641,7 +628,7 @@ public class SearchResultModel extends Model {
     // 필터링 처리한 임시 데이터
     List<SearchContentsBean> targetList = resultContentsBeans;
 
-    // 필터링 한 데이터가 있다면 
+    // 필터링 한 데이터가 있다면 그것을 이
     if (null != filterSearchResultBean) {
       // 일치하는 결과가 있음.
       if (null != filterSearchResultBean.getTagBeans() && filterSearchResultBean.getTagBeans().size() > 0) {
@@ -690,11 +677,6 @@ public class SearchResultModel extends Model {
 
 
   private boolean applyFilter(SearchRequestBean requestBean) {
-    return applyFilter(requestBean, appliedSearchFilterBeans);
-  }
-
-  private boolean applyFilter(SearchRequestBean requestBean, List<SearchFilterBean> list) {
-    // list 는 항상 null 임
     // 필터 추가
     boolean isApplied = false;
     if (null != searchFilterSectionBeans) {
@@ -713,12 +695,6 @@ public class SearchResultModel extends Model {
                     isApplied = true;
                     requestBean.setFilterPlace(requestBean.getFilterPlace() + StringUtil.HASH + tagBean.getTagNo());
                     break;
-//                  case SearchFilterBean.FILTER_TYPE_ORDER:
-//                    requestBean.setOrder(searchFilterBean.getFilterNo());
-//                    break;
-//                  case SearchFilterBean.FILTER_TYPE_PROPERTY:
-//                    requestBean.setFilter(requestBean.getFilter() + StringUtil.HASH + searchFilterBean.getFilterNo());
-//                    break;
                   default:
                     break;
                 }
@@ -759,6 +735,7 @@ public class SearchResultModel extends Model {
    * 필터링 취소
    */
   public void cancelFilter() {
+    isFilterApplied = false;
     filterSearchResultBean = null;
   }
 
@@ -768,11 +745,10 @@ public class SearchResultModel extends Model {
   public void commitFilter() {
 
     if (null == filterSearchResultBean) {
-      appliedSearchFilterBeans = null;
-      // 선택된 필터 없으므로 그냥 둠.
+      isFilterApplied = false;
     }
     else {
-      appliedSearchFilterBeans = new ArrayList<>(searchFilterBeans);
+      isFilterApplied = true;
       parseResult(filterSearchResultBean);
 
       onResult(new Event.Builder(Event.SUCCESS).integer(Event.SEARCH_TAG_CATEGORY).build());
@@ -786,8 +762,7 @@ public class SearchResultModel extends Model {
    * @return
    */
   public int getFilteredCount() {
-    if (null == getAppliedSearchFilterBeans() || getAppliedSearchFilterBeans().size() == 0) {
-      // 필터 적용하지 않았음
+    if (isFilterApplied == false) {
       return 0;
     }
 
@@ -800,6 +775,31 @@ public class SearchResultModel extends Model {
 
   }
 
+  /**
+   * filter data reset
+   */
+  public void resetFilter() {
+    isFilterApplied = false;
+
+    int len = searchFilterSectionBeans.size();
+    for (int i = 0; i < len; ++i) {
+      SearchFilterSectionBean bean = searchFilterSectionBeans.get(i);
+      for (SearchFilterBean filterBean : bean.getFilterBeans()) {
+        filterBean.setSelected(false);
+        if (SearchFilterBean.hasChildValue(filterBean)) {
+          for (FilterTagBean tagBean : filterBean.getTagBeans()) {
+            tagBean.setSelected(false);
+          }
+        }
+      }
+
+      // 정렬 순서 초기값
+      if (SearchFilterBean.FILTER_TYPE_ORDER.equals(bean.getSectionType())) {
+        bean.getFilterBeans().get(0).setSelected(true);
+      }
+    }
+  }
+
   interface IFilterDetailListener {
     void onCompleted(SearchFilterBean searchFilterBean);
 

+ 9 - 5
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/search/SearchResultPresenter.java

@@ -52,7 +52,7 @@ public class SearchResultPresenter extends Presenter<SearchResultModel, ISearchR
   }
 
   private void renderWithoutTags() {
-    view.setVisibleCategory(model.hasResult());
+    view.setVisibleCategory(model.hasResult() || model.isFilterApplied());
     view.drawCategory(model.getCategoryCheckBeans());
     renderContents();
   }
@@ -202,8 +202,14 @@ public class SearchResultPresenter extends Presenter<SearchResultModel, ISearchR
             model.cancelFilter();
           }
 
+          @Override
+          public void onFilterReset(SearchFilterDialog dialog) {
+            model.resetFilter();
+          }
+
           @Override
           public void onFilterDetail(SearchFilterDialog dialog, SearchFilterBean searchFilterBean) {
+            // 필터 세부 항목 요청
             model.loadFilterDetail(searchFilterBean, new SearchResultModel.IFilterDetailListener() {
               @Override
               public void onCompleted(SearchFilterBean searchFilterBean) {
@@ -218,9 +224,8 @@ public class SearchResultPresenter extends Presenter<SearchResultModel, ISearchR
           }
 
           @Override
-          public void onFilterChanged(SearchFilterDialog dialog, List<SearchFilterBean> pickedList) {
+          public void onFilterChanged(SearchFilterDialog dialog) {
             // 변경 된 필터를 적용한 컨텐츠의 수를 다이얼로그로 전달한다.
-            model.setFilter(null);
             model.loadFilteringContents(filterDialog, event -> {
               if (event.getEventId() == Event.SUCCESS) {
                 filterDialog.setContentsCount(event.getInteger());
@@ -229,10 +234,9 @@ public class SearchResultPresenter extends Presenter<SearchResultModel, ISearchR
           }
 
           @Override
-          public void onFilterResult(SearchFilterDialog dialog, List<SearchFilterBean> pickedList) {
+          public void onFilterResult(SearchFilterDialog dialog) {
             filterDialog = null;
             dialog.dispose();
-            Log.w("APP# FirstCategoryMainPresenter | onFilterResult", "|" + pickedList.size());
 
             model.commitFilter();
           }