Pārlūkot izejas kodu

[컨텐츠][New] 카드 타입에 html 페이지 추가

hyodong.min 7 gadi atpakaļ
vecāks
revīzija
705748ff1c

+ 71 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/bean/HtmlBean.java

@@ -0,0 +1,71 @@
+/*
+ * COPYRIGHT (c) 2018 All rights reserved by HANWHA LIFE.
+ */
+package kr.co.zumo.app.lifeplus.bean;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * HtmlBean
+ * <pre>
+ * </pre>
+ *
+ * @author 민효동
+ * @version 1.0
+ * @history 민효동   [2018. 12. 14.]   [최초 작성]
+ * @since 2018. 12. 14.
+ */
+public class HtmlBean extends JsonBeanBase {
+
+  /*
+  type
+  1:인앱
+  2:아웃링크
+
+  key
+  로그키값
+
+  url
+  이동할 링크주소
+
+  {
+  "type":type,
+  "key":key,
+  "url":url
+  };
+   */
+
+  public static final int TYPE_LINK = 1;
+  public static final int TYPE_APP = 2;
+
+  @SerializedName("type")
+  private int type;
+  @SerializedName("key")
+  private String key;
+  @SerializedName("url")
+  private String url;
+
+  public int getType() {
+    return type;
+  }
+
+  public void setType(int type) {
+    this.type = type;
+  }
+
+  public String getKey() {
+    return key;
+  }
+
+  public void setKey(String key) {
+    this.key = key;
+  }
+
+  public String getUrl() {
+    return url;
+  }
+
+  public void setUrl(String url) {
+    this.url = url;
+  }
+}

+ 27 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/bean/api/ContentsDetailBean.java

@@ -90,6 +90,33 @@ public class ContentsDetailBean extends LifeplusContentsBean {
     return url;
   }
 
+  /**
+   * 첫 번째 이미지의 타입을 반환한다.
+   * - 이미지 이외 동영상, html 일 수 있다.
+   *
+   * @return
+   */
+  public String getImageType() {
+    String type = "";
+    if (null != itemImageList && itemImageList.size() > 0) {
+      type = itemImageList.get(0).getImageType();
+    }
+    return type;
+  }
+
+  /**
+   * 이미지 리스트 중에서 첫 번째 것을 가져온다.
+   *
+   * @return
+   */
+  public String getHtmlUrl() {
+    String url = "";
+    if (null != itemImageList && itemImageList.size() > 0) {
+      url = itemImageList.get(0).getImageUrl();
+    }
+    return url;
+  }
+
   public String getItemType() {
     return itemType;
   }

+ 12 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/bean/api/LifeplusImageBean.java

@@ -19,6 +19,18 @@ import kr.co.zumo.app.lifeplus.bean.JsonBeanBase;
  */
 public class LifeplusImageBean extends JsonBeanBase {
 
+  /*
+  02: 표지이미지
+  08: 상세형 이미지
+  09: 동영상
+  10: HTML
+   */
+  public static final String TYPE_COVER = "02";
+  public static final String TYPE_DETAIL = "08";
+  public static final String TYPE_MOVIE = "09";
+  public static final String TYPE_HTML = "10";
+
+
   @SerializedName("imagNo")
   private String imageNumber;
   @SerializedName("imagType")

+ 2 - 1
app/src/main/java/kr/co/zumo/app/lifeplus/view/Event.java

@@ -121,6 +121,7 @@ public class Event {
   public static final int SCROLL = 93;
   public static final int SORT = 94;
   public static final int TUTORIAL = 95;
+  public static final int CLICK_HTML = 96;
 
 
   @Retention(RetentionPolicy.SOURCE)
@@ -133,7 +134,7 @@ public class Event {
     ACTION_BAR_SEARCH, ACTION_BAR_MENU, ACTION_BAR_TITLE, FIRST_CATEGORY, SECOND_CATEGORY, THIRD_CATEGORY, FOURTH_CATEGORY, FIFTH_CATEGORY,
     SWITCH, BOOK_MARK_DEFAULT, BOOK_MARK_LIST, ADD, MY_COIN_MAIN, MY_PURCHASE_HISTORY, GUIDE, ADD_BUCKET, MY_MAIN_GUEST, COUPON_MALL, CATEGORY_CLICK,
     MY_FAQ, UPDATE, FILTER, CLOSE, HELP, CONTENTS, MORE, BANNER, RECOMMEND, KAKAO_TALK, FACE_BOOK, CODE_COPY, EVENT, TAG, BOOKMARK, ORDER, DEFAULT, COMPLETE_BUCKET,
-    LIKE, FRAGMENT_STACK_EMPTY, OVER_VIEW, SHARE, CALL_INFO, LINK, HOME_PAGE, INSTAGRAM, ADDRESS, SCROLL, SORT, TUTORIAL
+    LIKE, FRAGMENT_STACK_EMPTY, OVER_VIEW, SHARE, CALL_INFO, LINK, HOME_PAGE, INSTAGRAM, ADDRESS, SCROLL, SORT, TUTORIAL, CLICK_HTML
   })
   public @interface ID {}
 

+ 40 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/view/command/WebCommand.java

@@ -0,0 +1,40 @@
+/*
+ * COPYRIGHT (c) 2018 All rights reserved by HANWHA LIFE.
+ */
+package kr.co.zumo.app.lifeplus.view.command;
+
+import android.content.Intent;
+import android.net.Uri;
+
+import kr.co.zumo.app.lifeplus.model.Model;
+import kr.co.zumo.app.lifeplus.view.IView;
+import kr.co.zumo.app.lifeplus.view.presenter.Presenter;
+
+/**
+ * WebCommand
+ * <pre>
+ * </pre>
+ *
+ * @author 민효동
+ * @version 1.0
+ * @history 민효동   [2018-10-08]   [최초 작성]
+ * @since 2018-10-08
+ */
+public class WebCommand extends Command<Model, IView, Presenter> {
+  private String url;
+
+  public WebCommand(String url) {
+    this.url = url;
+  }
+
+  @Override
+  public void execute(Model model, IView view, Presenter presenter) {
+    Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+    view.getActivity().startActivity(browserIntent);
+  }
+
+  @Override
+  public void dispose() {
+
+  }
+}

+ 32 - 12
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/contents/ContentsAdapter.java

@@ -13,6 +13,7 @@ import java.util.List;
 import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.bean.SeriesListBean;
 import kr.co.zumo.app.lifeplus.bean.api.ContentsDetailBean;
+import kr.co.zumo.app.lifeplus.bean.api.LifeplusImageBean;
 import kr.co.zumo.app.lifeplus.bean.api.SeriesItemBean;
 import kr.co.zumo.app.lifeplus.view.IEventListener;
 
@@ -44,6 +45,7 @@ public class ContentsAdapter extends RecyclerView.Adapter<ContentsHolder> {
   private static final int SERIES = 6;
   private static final int WITH_SHOWN_CONTENTS = 7;
   private static final int HTML = 8;
+  private static final int MOVIE = 9;
 
 
   public ContentsAdapter(Context context, String listType, List<ContentsDetailBean> contentsDetailBeans, List<SeriesItemBean> seriesItemBeans, SeriesItemBean seriesInfo, IEventListener listener) {
@@ -98,18 +100,18 @@ public class ContentsAdapter extends RecyclerView.Adapter<ContentsHolder> {
       listener.onEvent(event);
     };
 
-    if (holder instanceof ContentsSeriesHolder) {
-      SeriesListBean seriesListBean = new SeriesListBean();
-      seriesListBean.setSeriesInfo(seriesInfo);
-      seriesListBean.setSeriesItemList(seriesItemBeans);
-      holder.bind(position, seriesListBean, eventListener);
-    }
-    else if (holder instanceof ContentsCardHolder) {
+    if (holder instanceof ContentsCardHolder) {
       ((ContentsCardHolder) holder).setItemCount(getItemCount());
       ContentsDetailBean bean = contentsDetailBeans.get(position);
       holder.bind(position, bean, eventListener);
 
     }
+    else if (holder instanceof ContentsSeriesHolder) {
+      SeriesListBean seriesListBean = new SeriesListBean();
+      seriesListBean.setSeriesInfo(seriesInfo);
+      seriesListBean.setSeriesItemList(seriesItemBeans);
+      holder.bind(position, seriesListBean, eventListener);
+    }
     else {
       Log.e("APP#  ContentsAdapter | onBindViewHolder", "| position: " + position + " - " + this.hashCode());
       ContentsDetailBean bean = contentsDetailBeans.get(position);
@@ -167,9 +169,6 @@ public class ContentsAdapter extends RecyclerView.Adapter<ContentsHolder> {
         case ContentsDetailBean.TYPE_CARD:
           type = CARD_LISTICLE_COVER;
           break;
-        case ContentsDetailBean.TYPE_HTML:
-          type = HTML;
-          break;
         default:
           break;
       }
@@ -181,10 +180,10 @@ public class ContentsAdapter extends RecyclerView.Adapter<ContentsHolder> {
           type = LISTICLE_DETAIL;
           break;
         case ContentsDetailBean.TYPE_CARD_LISTICLE:
-          type = CARD_LISTICLE_DETAIL;
+          type = getCardType(position, CARD_LISTICLE_DETAIL);
           break;
         case ContentsDetailBean.TYPE_CARD:
-          type = CARD_DETAIL;
+          type = getCardType(position, CARD_DETAIL);
           break;
         default:
           break;
@@ -193,6 +192,27 @@ public class ContentsAdapter extends RecyclerView.Adapter<ContentsHolder> {
     return type;
   }
 
+  private int getCardType(int position, int defaultType) {
+    int type = defaultType;
+
+    ContentsDetailBean bean = contentsDetailBeans.get(position);
+    String itemType = bean.getImageType();
+    if (LifeplusImageBean.TYPE_COVER.equals(itemType)) {
+      type = CARD_DETAIL;
+    }
+    else if (LifeplusImageBean.TYPE_DETAIL.equals(itemType)) {
+      type = CARD_DETAIL;
+    }
+    else if (LifeplusImageBean.TYPE_MOVIE.equals(itemType)) {
+      type = MOVIE;
+    }
+    else if (LifeplusImageBean.TYPE_HTML.equals(itemType)) {
+      type = HTML;
+    }
+
+    return type;
+  }
+
   @Override
   public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
     super.onAttachedToRecyclerView(recyclerView);

+ 62 - 2
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/contents/ContentsHtmlHolder.java

@@ -1,12 +1,23 @@
 package kr.co.zumo.app.lifeplus.view.screen.contents;
 
+import android.annotation.SuppressLint;
+import android.net.http.SslError;
+import android.util.Log;
 import android.view.View;
+import android.webkit.JavascriptInterface;
+import android.webkit.SslErrorHandler;
+import android.webkit.WebSettings;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 
+import com.google.gson.Gson;
+
 import kr.co.zumo.app.R;
+import kr.co.zumo.app.lifeplus.bean.HtmlBean;
 import kr.co.zumo.app.lifeplus.bean.api.ContentsDetailBean;
 import kr.co.zumo.app.lifeplus.util.StringUtil;
+import kr.co.zumo.app.lifeplus.view.Event;
+import kr.co.zumo.app.lifeplus.view.WebConstant;
 
 /**
  * ContentsHtmlHolder
@@ -27,9 +38,12 @@ public class ContentsHtmlHolder extends ContentsHolder<ContentsDetailBean> {
     webView = itemView.findViewById(R.id.web_view);
   }
 
+  @SuppressLint("JavascriptInterface")
   @Override
   protected void bindInternal() {
-    String url = bean.getContentsUrl();
+    Log.w("APP# ContentsHtmlHolder | bindInternal", "|" + bean.toJson());
+
+    String url = bean.getHtmlUrl();
     if (null != webView && StringUtil.isFull(url)) {
       webView.setWebViewClient(new WebViewClient() {
         @Override
@@ -37,13 +51,59 @@ public class ContentsHtmlHolder extends ContentsHolder<ContentsDetailBean> {
           view.loadUrl(url);
           return true;
         }
+
+        @Override
+        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
+          Log.w("APP# ContentsHtmlHolder | onReceivedSslError", "|" + "message: " + error.toString());
+          handler.proceed();
+        }
       });
-      webView.getSettings().setJavaScriptEnabled(true);
+
+      init(webView);
+
+      webView.addJavascriptInterface(this, WebConstant.OBJECT_ID);
 
       webView.loadUrl(url);
     }
   }
 
+  @JavascriptInterface
+  public void sendMessage(String json) {
+    try {
+      HtmlBean bean = new Gson().fromJson(json, HtmlBean.class);
+      if (null != bean) {
+        listener.onEvent(new Event.Builder(Event.CLICK_HTML).json(json).build());
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  private void init(WebView webView) {
+    WebSettings settings = webView.getSettings();
+    // Javascript 사용하기
+    settings.setJavaScriptEnabled(true);
+    // WebView 내장 줌 사용여부
+    settings.setBuiltInZoomControls(true);
+    // 화면에 맞게 WebView 사이즈를 정의
+    settings.setLoadWithOverviewMode(true);
+    // ViewPort meta tag를 활성화 여부
+    settings.setUseWideViewPort(true);
+    // 줌 컨트롤 사용 여부
+    settings.setDisplayZoomControls(true);
+    // 사용자 제스처를 통한 줌 기능 활성화 여부
+    settings.setSupportZoom(true);
+    // TextEncoding 이름 정의
+    settings.setDefaultTextEncodingName("UTF-8");
+
+    // Setting Local Storage
+    settings.setDatabaseEnabled(true);
+    settings.setDomStorageEnabled(true);
+
+    // 캐쉬 사용 방법을 정의
+    settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
+  }
+
   @Override
   public void attach() {
   }

+ 13 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/contents/ContentsPresenter.java

@@ -6,6 +6,7 @@ import android.widget.Toast;
 
 import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.bean.ContentsDeliveryBean;
+import kr.co.zumo.app.lifeplus.bean.HtmlBean;
 import kr.co.zumo.app.lifeplus.bean.api.ContentsDetailBean;
 import kr.co.zumo.app.lifeplus.bean.api.LifeplusContentsBean;
 import kr.co.zumo.app.lifeplus.helper.NavigationBar;
@@ -14,6 +15,7 @@ import kr.co.zumo.app.lifeplus.util.ResourceUtil;
 import kr.co.zumo.app.lifeplus.util.StringUtil;
 import kr.co.zumo.app.lifeplus.view.DoubleChecker;
 import kr.co.zumo.app.lifeplus.view.Event;
+import kr.co.zumo.app.lifeplus.view.command.WebCommand;
 import kr.co.zumo.app.lifeplus.view.dialog.ConfirmDialog;
 import kr.co.zumo.app.lifeplus.view.dialog.DialogBuilder;
 import kr.co.zumo.app.lifeplus.view.dialog.DialogID;
@@ -179,6 +181,17 @@ public class ContentsPresenter extends ContentsBasePresenter<ContentsModel, ICon
       case Event.NONE:
         showLastPageToast();
         break;
+      case Event.CLICK_HTML:
+        // html 의 자바스크립트를 통해서 전달된 데이터
+        HtmlBean htmlBean = event.fromJson(HtmlBean.class);
+        if (htmlBean.getType() == HtmlBean.TYPE_APP) {
+          model.setDeliveryPackaging(htmlBean.getUrl());
+          go(ScreenID.WEB);
+        }
+        else if (htmlBean.getType() == HtmlBean.TYPE_LINK) {
+          onCommand(new WebCommand(htmlBean.getUrl()));
+        }
+        break;
       default:
         break;
     }

+ 2 - 1
app/src/main/res/layout/contents_html.xml

@@ -4,7 +4,8 @@
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
-  android:layout_height="match_parent">
+  android:layout_height="match_parent"
+  android:descendantFocusability="blocksDescendants">
 
   <WebView
     android:id="@+id/web_view"

+ 1 - 0
app/src/main/res/layout/fragment_contents_detail.xml

@@ -3,6 +3,7 @@
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
+  android:descendantFocusability="blocksDescendants"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
app/src/sandbox/java/kr/co/zumo/app/lifeplus/network/api/LifeplusAPIService.java