Browse Source

添加图片轮播页面

Fenix Wang 8 years ago
parent
commit
699f17cecf

+ 15 - 12
app/app.iml

@@ -59,13 +59,6 @@
       <sourceFolder url="file://$MODULE_DIR$/assets" type="java-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
@@ -73,9 +66,13 @@
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/build/.DS_Store" />
-      <excludeFolder url="file://$MODULE_DIR$/build/freeline" />
-      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/.DS_Store" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
@@ -90,10 +87,8 @@
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/multi-dex" />
-      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard-rules" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
-      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res.job" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
@@ -146,5 +141,13 @@
     <orderEntry type="library" exported="" name="support-compat-25.3.1" level="project" />
     <orderEntry type="library" exported="" name="animated-vector-drawable-25.3.1" level="project" />
     <orderEntry type="module" module-name="uikit" exported="" />
+    <orderEntry type="library" exported="" name="java-json" level="project" />
+    <orderEntry type="library" exported="" name="renderscript-v8" level="project" />
+    <orderEntry type="library" exported="" name="glide-3.7.0" level="project" />
+    <orderEntry type="library" exported="" name="nim-avchat-4.0.0" level="project" />
+    <orderEntry type="library" exported="" name="constraint-layout-solver-1.0.2" level="project" />
+    <orderEntry type="library" exported="" name="nim-basesdk-4.0.0" level="project" />
+    <orderEntry type="library" exported="" name="fastjson-1.1.34.android" level="project" />
+    <orderEntry type="library" exported="" name="nim-lucene-4.0.0" level="project" />
   </component>
 </module>

+ 5 - 0
uikit/AndroidManifest.xml

@@ -144,6 +144,11 @@
             android:configChanges="keyboardHidden"
             android:theme="@style/AppTheme.NoActionBar"/>
 
+        <activity
+            android:name="com.netease.nim.uikit.session.activity.WatchPictureActivity"
+            android:configChanges="keyboardHidden"
+            android:theme="@style/AppTheme.NoActionBar"/>
+
         <activity android:name=".team.activity.TeamMemberListActivity"
             android:screenOrientation="portrait"
             android:theme="@style/AppTheme.NoActionBar"/>

+ 17 - 2
uikit/res/layout/nim_watch_picture_activity.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/watch_picture_activity_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
@@ -11,11 +12,25 @@
 
     <!-- <include layout="@layout/watch_picture_show_more_action_layout" /> -->
 
+    <include layout="@layout/nim_watch_media_download_progress_layout" />
+
     <android.support.v4.view.ViewPager
         android:id="@+id/view_pager_image"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
+        android:layout_height="match_parent" />
 
-    <include layout="@layout/nim_watch_media_download_progress_layout" />
+    <AbsoluteLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom">
+
+        <TextView
+            android:id="@+id/watch_picture_text"
+            android:layout_width="match_parent"
+            android:layout_height="40dp"
+            android:layout_weight="1"
+            android:textAlignment="center"
+            android:textColor="@color/white" />
+    </AbsoluteLayout>
 
 </FrameLayout>

+ 5 - 3
uikit/src/com/netease/nim/uikit/common/ui/imageview/BaseZoomableImageView.java

@@ -113,6 +113,8 @@ public abstract class BaseZoomableImageView extends View {
 
 	private boolean landscape = false;
 
+	public boolean bitmapRecyclable = true;
+
 	// Programatic entry point
 	public BaseZoomableImageView(Context context) {
 		super(context);
@@ -162,7 +164,7 @@ public abstract class BaseZoomableImageView extends View {
 
 	// Free the bitmaps and matrices
 	public void clear(){
-		if(mBitmap!=null && !mBitmap.isRecycled()) {
+		if(mBitmap!=null && !mBitmap.isRecycled() && bitmapRecyclable) {
 			mBitmap.recycle();
 		}
 		mBitmap = null;
@@ -240,7 +242,7 @@ public abstract class BaseZoomableImageView extends View {
 			mBaseMatrix.reset();
 			this.mBitmap = bitmap;
 		}
-		if (oldBitmap != null && oldBitmap != mBitmap && !oldBitmap.isRecycled()) {
+		if (oldBitmap != null && oldBitmap != mBitmap && !oldBitmap.isRecycled() && bitmapRecyclable) {
 			oldBitmap.recycle();
 		}
 
@@ -283,7 +285,7 @@ public abstract class BaseZoomableImageView extends View {
 			mBaseMatrix.reset();
 			this.mBitmap = bitmap;
 		}
-		if (oldBitmap != null && !oldBitmap.isRecycled()) {
+		if (oldBitmap != null && !oldBitmap.isRecycled() && bitmapRecyclable) {
 			oldBitmap.recycle();
 		}
 

+ 10 - 0
uikit/src/com/netease/nim/uikit/session/activity/IWatchPictureData.java

@@ -0,0 +1,10 @@
+package com.netease.nim.uikit.session.activity;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface IWatchPictureData extends Serializable
+{
+    List<String> getPics();
+    List<String> getThumbs();
+}

+ 301 - 0
uikit/src/com/netease/nim/uikit/session/activity/WatchPictureActivity.java

@@ -0,0 +1,301 @@
+package com.netease.nim.uikit.session.activity;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.MediaStore;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.ViewPager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.AbsoluteLayout;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.netease.nim.uikit.R;
+import com.netease.nim.uikit.common.activity.UI;
+import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog;
+import com.netease.nim.uikit.common.ui.imageview.BaseZoomableImageView;
+import com.netease.nim.uikit.common.ui.imageview.ImageGestureListener;
+import com.netease.nim.uikit.common.util.C;
+import com.netease.nim.uikit.common.util.file.AttachmentStore;
+import com.netease.nim.uikit.common.util.media.BitmapDecoder;
+import com.netease.nim.uikit.common.util.media.ImageUtil;
+import com.netease.nim.uikit.common.util.storage.StorageUtil;
+import com.netease.nimlib.sdk.AbortableFuture;
+import com.netease.nimlib.sdk.NIMClient;
+import com.netease.nimlib.sdk.Observer;
+import com.netease.nimlib.sdk.msg.MsgService;
+import com.netease.nimlib.sdk.msg.MsgServiceObserve;
+import com.netease.nimlib.sdk.msg.attachment.ImageAttachment;
+import com.netease.nimlib.sdk.msg.constant.AttachStatusEnum;
+import com.netease.nimlib.sdk.msg.model.IMMessage;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Created by fenix on 2017/8/22.
+ */
+
+public class WatchPictureActivity extends UI {
+
+    private static final String INTENT_EXTRA_IMAGE = "INTENT_EXTRA_IMAGE";
+
+    private Handler handler;
+
+    private int firstDisplayImageIndex = 0;
+    private WatchPictureData data;
+
+    private boolean newPageSelected = false;
+
+    private View loadingLayout;
+    private BaseZoomableImageView image;
+    protected CustomAlertDialog alertDialog;
+    private ViewPager imageViewPager;
+    private PagerAdapter adapter;
+
+    private HashMap<String, Bitmap> thumbMap;
+    private HashMap<String, Bitmap> picMap;
+
+    private TextView textView;
+
+    public static void start(Context context, List<String> picPathList, List<String> thumbPathList, int firstIndex) {
+        Intent intent = new Intent();
+        WatchPictureData data = new WatchPictureData(picPathList, thumbPathList, firstIndex);
+        intent.putExtra(INTENT_EXTRA_IMAGE, data);
+        intent.setClass(context, WatchPictureActivity.class);
+        context.startActivity(intent);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstatnceState){
+        super.onCreate(savedInstatnceState);
+        setContentView(R.layout.nim_watch_picture_activity);
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+        this.data = (WatchPictureData) getIntent().getSerializableExtra(INTENT_EXTRA_IMAGE);
+        this.firstDisplayImageIndex = this.data.getFirstIndex();
+        findViews();
+        setViewPagerAdapter();
+
+        handler = new Handler();
+
+        thumbMap = new HashMap<String, Bitmap>();
+        picMap = new HashMap<String, Bitmap>();
+    }
+
+    @Override
+    protected void onDestroy() {
+        imageViewPager.setAdapter(null);
+        super.onDestroy();
+    }
+
+    private void findViews() {
+        alertDialog = new CustomAlertDialog(this);
+        loadingLayout = findViewById(R.id.loading_layout);
+
+        imageViewPager = (ViewPager) findViewById(R.id.view_pager_image);
+
+        textView = (TextView) findViewById(R.id.watch_picture_text);
+    }
+
+    private void setViewPagerAdapter() {
+        adapter = new PagerAdapter() {
+            @Override
+            public int getCount() {
+                return data == null ? 0 : data.size();
+            }
+
+            @Override
+            public void notifyDataSetChanged() {
+                super.notifyDataSetChanged();
+            }
+
+            @Override
+            public void destroyItem(ViewGroup container, int position, Object object) {
+                View layout = (View) object;
+                BaseZoomableImageView iv = (BaseZoomableImageView) layout.findViewById(R.id.watch_image_view);
+                iv.clear();
+                container.removeView(layout);
+            }
+
+            @Override
+            public boolean isViewFromObject(View view, Object object) {
+                return (view == object);
+            }
+
+            @Override
+            public Object instantiateItem(ViewGroup container, int position) {
+                ViewGroup layout;
+                layout = (ViewGroup) LayoutInflater.from(WatchPictureActivity.this).inflate(R.layout.image_layout_multi_touch, null);
+                layout.setBackgroundColor(Color.BLACK);
+
+                container.addView(layout);
+                layout.setTag(position);
+
+                if (position == firstDisplayImageIndex) {
+                    onViewPagerSelected(position);
+                }
+
+                return layout;
+            }
+
+            @Override
+            public int getItemPosition(Object object) {
+                return POSITION_NONE;
+            }
+        };
+
+        imageViewPager.setAdapter(adapter);
+        imageViewPager.setOffscreenPageLimit(9);
+        imageViewPager.setCurrentItem(firstDisplayImageIndex);
+        imageViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+            @Override
+            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+                if (positionOffset == 0f && newPageSelected) {
+                    newPageSelected = false;
+                    onViewPagerSelected(position);
+                }
+            }
+
+            @Override
+            public void onPageSelected(int position) {
+                newPageSelected = true;
+            }
+
+            @Override
+            public void onPageScrollStateChanged(int state) {
+
+            }
+        });
+    }
+
+    private void onViewPagerSelected(int position) {
+        updateCurrentImageView(position);
+        onImageViewFound(image);
+        requestOriImage(data.getPics().get(position));
+    }
+
+    // 初始化每个view的image
+    protected void updateCurrentImageView(final int position) {
+        View currentLayout = imageViewPager.findViewWithTag(position);
+        if (currentLayout == null) {
+            ViewCompat.postOnAnimation(imageViewPager, new Runnable() {
+
+                @Override
+                public void run() {
+                    updateCurrentImageView(position);
+                }
+            });
+            return;
+        };
+        image = (BaseZoomableImageView) currentLayout.findViewById(R.id.watch_image_view);
+        image.bitmapRecyclable = false;
+
+        textView.setText(""+(position+1)+"/"+data.size());
+    }
+
+    // 若图片已下载,直接显示图片;若图片未下载,则下载图片
+    private void requestOriImage(final String path) {
+
+        Glide.with(this.getApplicationContext()).load(path).asBitmap().diskCacheStrategy(DiskCacheStrategy.ALL).into(new SimpleTarget<Bitmap>() {
+
+            @Override
+            public void onLoadStarted(Drawable placeholder) {
+                loadingLayout.setVisibility(View.VISIBLE);
+                Log.d("onLoadStarted", path);
+            }
+
+            @Override
+            public void onLoadFailed(Exception e, Drawable errorDrawable) {
+                onDownloadFailed();
+            }
+
+            @Override
+            public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
+                Log.d("onResourceReady", path);
+                loadingLayout.setVisibility(View.GONE);
+                image.setImageBitmap(resource);
+            }
+        });
+    }
+
+    private boolean isOriginImageHasDownloaded(final String picPath) {
+        if (!TextUtils.isEmpty(picPath)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * ******************************** 设置图片 *********************************
+     */
+
+    private int getImageResOnLoading() {
+        return R.drawable.nim_image_default;
+    }
+
+    private int getImageResOnFailed() {
+        return R.drawable.nim_image_download_failed;
+    }
+
+    private void onDownloadFailed() {
+        loadingLayout.setVisibility(View.GONE);
+        image.setImageBitmap(ImageUtil.getBitmapFromDrawableRes(getImageResOnFailed()));
+        Toast.makeText(this, R.string.download_picture_fail, Toast.LENGTH_LONG).show();
+    }
+
+    /**
+     * ***********************************图片点击事件*******************************************
+     */
+
+    // 设置图片点击事件
+    protected void onImageViewFound(BaseZoomableImageView imageView) {
+        imageView.setImageGestureListener(new ImageGestureListener() {
+
+            @Override
+            public void onImageGestureSingleTapConfirmed() {
+                onImageViewTouched();
+            }
+
+            @Override
+            public void onImageGestureLongPress() {
+                //showWatchPictureAction();
+            }
+
+            @Override
+            public void onImageGestureFlingDown() {
+                finish();
+            }
+        });
+    }
+
+    // 图片单击
+    protected void onImageViewTouched() {
+        finish();
+    }
+
+
+
+}
+
+

+ 34 - 0
uikit/src/com/netease/nim/uikit/session/activity/WatchPictureData.java

@@ -0,0 +1,34 @@
+package com.netease.nim.uikit.session.activity;
+
+import java.util.List;
+
+public class WatchPictureData implements IWatchPictureData
+{
+    private List<String> pics;
+    private List<String> thumbs;
+    private int firstIndex;
+
+    public WatchPictureData(List<String> pics, List<String> thumbs, int firstIndex)
+    {
+        this.firstIndex = firstIndex;
+        this.pics = pics;
+        this.thumbs = thumbs;
+    }
+
+    public int getFirstIndex()
+    {
+        return firstIndex;
+    }
+
+    public List<String> getPics()
+    {
+        return pics;
+    }
+
+    public List<String> getThumbs()
+    {
+        return thumbs;
+    }
+
+    public int size() { return pics.size(); }
+}

+ 0 - 2
uikit/uikit.iml

@@ -73,8 +73,6 @@
       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/build/.DS_Store" />
-      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/.DS_Store" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotations" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />