diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index ae78c11..554ffcd 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,5 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml new file mode 100644 index 0000000..efc9bd2 --- /dev/null +++ b/.idea/dbnavigator.xml @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 660b116..c7cabdb 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,8 +2,11 @@ + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index d85597c..6e7467c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -129,9 +129,9 @@ android { implementation 'net.dankito.richtexteditor:richtexteditor-android:2.0.8' implementation(name: 'alipaySdk-15.5.9', ext: 'aar') + implementation files('libs/pldroid-player-2.1.9.jar') + implementation project(':ninegridview') } - repositories { - mavenCentral() - } + } diff --git a/app/libs/arm64-v8a/libQPlayer.so b/app/libs/arm64-v8a/libQPlayer.so new file mode 100644 index 0000000..f1d76ac Binary files /dev/null and b/app/libs/arm64-v8a/libQPlayer.so differ diff --git a/app/libs/arm64-v8a/libqcOpenSSL.so b/app/libs/arm64-v8a/libqcOpenSSL.so new file mode 100644 index 0000000..1813fbe Binary files /dev/null and b/app/libs/arm64-v8a/libqcOpenSSL.so differ diff --git a/app/libs/armeabi-v7a/libQPlayer.so b/app/libs/armeabi-v7a/libQPlayer.so new file mode 100644 index 0000000..a58cd9b Binary files /dev/null and b/app/libs/armeabi-v7a/libQPlayer.so differ diff --git a/app/libs/armeabi-v7a/libqcOpenSSL.so b/app/libs/armeabi-v7a/libqcOpenSSL.so new file mode 100644 index 0000000..a073ab6 Binary files /dev/null and b/app/libs/armeabi-v7a/libqcOpenSSL.so differ diff --git a/app/libs/armeabi/libQPlayer.so b/app/libs/armeabi/libQPlayer.so new file mode 100644 index 0000000..45f8dc5 Binary files /dev/null and b/app/libs/armeabi/libQPlayer.so differ diff --git a/app/libs/armeabi/libqcOpenSSL.so b/app/libs/armeabi/libqcOpenSSL.so new file mode 100644 index 0000000..924a7af Binary files /dev/null and b/app/libs/armeabi/libqcOpenSSL.so differ diff --git a/app/libs/pldroid-player-2.1.9.jar b/app/libs/pldroid-player-2.1.9.jar new file mode 100644 index 0000000..e4a5552 Binary files /dev/null and b/app/libs/pldroid-player-2.1.9.jar differ diff --git a/app/libs/x86/libQPlayer.so b/app/libs/x86/libQPlayer.so new file mode 100644 index 0000000..bcf3ba1 Binary files /dev/null and b/app/libs/x86/libQPlayer.so differ diff --git a/app/libs/x86/libqcOpenSSL.so b/app/libs/x86/libqcOpenSSL.so new file mode 100644 index 0000000..36a95a0 Binary files /dev/null and b/app/libs/x86/libqcOpenSSL.so differ diff --git a/app/src/androidTest/java/com/sl/house_property/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/sl/house_property/ExampleInstrumentedTest.java deleted file mode 100644 index f176425..0000000 --- a/app/src/androidTest/java/com/sl/house_property/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.sl.house_property; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("com.sl.HouseProperty", appContext.getPackageName()); - } -} diff --git a/app/src/main/java/com/sl/house_property/LogoActivity.java b/app/src/main/java/com/sl/house_property/LogoActivity.java index 14debe7..33234b8 100644 --- a/app/src/main/java/com/sl/house_property/LogoActivity.java +++ b/app/src/main/java/com/sl/house_property/LogoActivity.java @@ -28,8 +28,9 @@ public class LogoActivity extends Activity{ imaloder.postDelayed(new Runnable() { @Override public void run() { + finish(); startActivity( new Intent(LogoActivity.this, MainTabActivity.class)); - finish(); + } },delaytime); diff --git a/app/src/main/java/com/sl/house_property/Main1Fragment.java b/app/src/main/java/com/sl/house_property/Main1Fragment.java index 25b54aa..4111b0d 100644 --- a/app/src/main/java/com/sl/house_property/Main1Fragment.java +++ b/app/src/main/java/com/sl/house_property/Main1Fragment.java @@ -210,7 +210,7 @@ public class Main1Fragment extends BaseFragment implements *

* See the Android Training lesson Communicating with Other Fragments for more information. + * >Communicating with Other Fragments for more in+formation. */ public interface OnFragmentInteractionListener { // TODO: Update argument type and name @@ -282,6 +282,7 @@ public class Main1Fragment extends BaseFragment implements mDataBinding.recyView.requestFocus(); //设置焦点不需要 } + private void addRecycleVerization(ArrayList lsit) { mDataBinding.maincontrol.setVisibility(View.VISIBLE); BaseRecycleViewAdapter baseRecycleViewAdapter = (BaseRecycleViewAdapter) mDataBinding.recyView.getAdapter(); diff --git a/app/src/main/java/com/sl/house_property/MainActivity.java b/app/src/main/java/com/sl/house_property/MainActivity.java index 65e2c9e..8edeb5c 100644 --- a/app/src/main/java/com/sl/house_property/MainActivity.java +++ b/app/src/main/java/com/sl/house_property/MainActivity.java @@ -65,15 +65,15 @@ public class MainActivity extends Activity { private void onceOrNot() { // TODO Auto-generated method stub int once = Config.getInstance(MainActivity.this).getInt(ConfigTitiles.ONCEORNOT, 0); - /*if (once == 0) { + if (once == 0) { Config.getInstance(getApplicationContext()).put(ConfigTitiles.ONCEORNOT, 1); onceStart(); return; - } else {*/ + } else { //onceStart(); otherStart(); - /* return; - }*/ + return; + } } private void onceStart() { diff --git a/app/src/main/java/com/sl/house_property/MainTabActivity.java b/app/src/main/java/com/sl/house_property/MainTabActivity.java index 53c7fe2..0801f07 100644 --- a/app/src/main/java/com/sl/house_property/MainTabActivity.java +++ b/app/src/main/java/com/sl/house_property/MainTabActivity.java @@ -11,6 +11,7 @@ import android.widget.RadioButton; import android.widget.RadioGroup; import com.sl.house_property.databinding.ActivityMainTabBinding; +import com.sl.house_property.discovery.DiscoveryFragment; import tools.Config; @@ -27,13 +28,13 @@ implements View.OnClickListener,MainFragment.OnFragmentInteractionListener, */ public static final int RESUlT_CODE_0 = 201;//首页 - public static final int RESUlT_CODE_1 = 202;//商城 - public static final int RESUlT_CODE_2 = 203;//缴费 - public static final int RESUlT_CODE_3 = 204;//家政 + public static final int RESUlT_CODE_1 = 202;//发现 + public static final int RESUlT_CODE_2 = 203;//购物车 + // public static final int RESUlT_CODE_3 = 204;// public static final int RESUlT_CODE_4 = 205;//我的 private RadioGroup radioGroup; private MainFragment fragment0; - private Main1Fragment fragment1; + private DiscoveryFragment fragment1; private Main3Fragment fragment2; private Main2Fragment fragment3; private Main4Fragment fragment4; @@ -106,7 +107,7 @@ implements View.OnClickListener,MainFragment.OnFragmentInteractionListener, // mDataBinding.getRoot().setBackground(getResources().getDrawable(R.drawable.background_slowly)); if (fragment1 == null) { - fragment1 = Main1Fragment.newInstance("", ""); + fragment1 = DiscoveryFragment.newInstance("", ""); fragmentTransaction.add(R.id.mycontent, fragment1, "fragment1"); } else { diff --git a/app/src/main/java/com/sl/house_property/MyApplication.java b/app/src/main/java/com/sl/house_property/MyApplication.java index 0d13605..3d5784c 100644 --- a/app/src/main/java/com/sl/house_property/MyApplication.java +++ b/app/src/main/java/com/sl/house_property/MyApplication.java @@ -7,11 +7,14 @@ import android.os.StrictMode; import android.support.multidex.MultiDex; import android.util.Log; +import com.lzy.ninegrid.NineGridView; + import java.util.LinkedList; import java.util.List; import tools.CrashHandler; import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard; +import utils.NineImageLoader; //import cn.jpush.im.android.api.JMessageClient; /** @@ -64,7 +67,7 @@ public class MyApplication extends Application{ StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); - + NineGridView.setImageLoader(new NineImageLoader()); } diff --git a/app/src/main/java/com/sl/house_property/cart/CartFragment.java b/app/src/main/java/com/sl/house_property/cart/CartFragment.java new file mode 100644 index 0000000..234a7ce --- /dev/null +++ b/app/src/main/java/com/sl/house_property/cart/CartFragment.java @@ -0,0 +1,4 @@ +package com.sl.house_property.cart; + +public class CartFragment { +} diff --git a/app/src/main/java/com/sl/house_property/discovery/DiscoveryFragment.java b/app/src/main/java/com/sl/house_property/discovery/DiscoveryFragment.java new file mode 100644 index 0000000..2f8c14a --- /dev/null +++ b/app/src/main/java/com/sl/house_property/discovery/DiscoveryFragment.java @@ -0,0 +1,301 @@ +package com.sl.house_property.discovery; + +import android.app.ProgressDialog; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.LayoutInflater; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.dalong.refreshlayout.OnRefreshListener; +import com.google.gson.Gson; +import com.google.gson.internal.LinkedTreeMap; +import com.google.gson.reflect.TypeToken; +import com.lzy.ninegrid.ImageInfo; +import com.lzy.ninegrid.preview.NineGridViewClickAdapter; +import com.sl.house_property.BaseActivity; +import com.sl.house_property.BaseFragment; +import com.sl.house_property.R; +import com.sl.house_property.databinding.FragmentDiscoveryBinding; +import com.sl.house_property.databinding.ItemDiscoveryBinding; +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Target; + +import org.json.JSONObject; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import adapter.BaseRecycleViewAdapter; +import entity.DiscoveryListEntity; +import entity.RegisterUser; +import http.ApiConfig; +import my_loader.Loader; +import my_loader.Resultcode; +import my_view.tao_bao_refresh.FullyGridLayoutManager; +import rx.Subscription; +import rx.functions.Action1; +import tools.Config; +import tools.PicassoRoundTransform; +import utils.Md5; + +public class DiscoveryFragment extends BaseFragment { + private static final String ARG_PARAM1 = "param1"; + private static final String ARG_PARAM2 = "param2"; + private String mParam1; + private String mParam2; + BaseActivity baseActivity; + private ProgressDialog progressDialog; + private ArrayList discoveryListEntities; + + @Override + protected int getLayoutId() { + return R.layout.fragment_discovery; + } + + @Override + public void loadData() { + + } + + private int page = 1; + + @Override + protected void onCreateVew(LayoutInflater inflater, Bundle savedInstanceState) { + super.onCreateVew(inflater, savedInstanceState); + baseActivity = (BaseActivity) getActivity(); + progressDialog = new ProgressDialog(baseActivity); + mDataBinding.rl.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh() { + page = 1; + getlist(page); + + } + + @Override + public void onLoadMore() { + + } + }); + mDataBinding.rl.setAutoRefresh(true); + intRecycleView(); + } + + private Loader mGankLoader; + + private void getlist(int mypage) { + RegisterUser user = + Config.getInstance(getContext()).getUser(); + Map map = new HashMap<>(); + if (user != null) { + map.put("userid", user.getUserid()); + } else { + map.put("userid", 0 + ""); + } + map.put("app", "Goods"); + map.put("class", "GoodsLists"); + map.put("page", mypage + ""); + map.put("sign", Md5.md5("Goods" + "GoodsLists" + Md5.secret)); + getGankList(ApiConfig.BASE_URL, map, getResources().getString(R.string.requsting), mypage); + } + + private void intRecycleView() { + FullyGridLayoutManager mgr = new FullyGridLayoutManager(getActivity(), 1); + mgr.setOrientation(FullyGridLayoutManager.VERTICAL); + mgr.setSmoothScrollbarEnabled(true); + mDataBinding.recyView.setLayoutManager(mgr); + BaseRecycleViewAdapter baseRecycleViewAdapter = new BaseRecycleViewAdapter(getActivity(), R.layout.item_discovery); + discoveryListEntities = new ArrayList<>(); + baseRecycleViewAdapter.setOnBindViewHolder(new BaseRecycleViewAdapter.BindView() { + @Override + public void onBindViewHolder(Object b, int position) { + if (!(position >= discoveryListEntities.size())) { + ItemDiscoveryBinding homeGridAdapterItemBinding = (ItemDiscoveryBinding) b; + // homeGridAdapterItemBinding.setMyentity(discoveryListEntities.get(position)); + DiscoveryListEntity discoveryListEntity = discoveryListEntities.get(position); +// Picasso.with(getActivity()).load(discoveryListEntity.getAvatar()) +// .placeholder(R.mipmap.icon_default_rectangle) +// .transform(new PicassoRoundTransform()) +// .into(homeGridAdapterItemBinding.imageHead); + RequestOptions requestOptions = new RequestOptions(); + requestOptions.placeholder(R.mipmap.icon_default_rectangle); + requestOptions.error(R.mipmap.icon_default_rectangle); + + Glide.with(getContext()).load(discoveryListEntity.getAvatar()) + .apply(requestOptions) + .into(homeGridAdapterItemBinding.imageHead); + ArrayList imageInfos = new ArrayList<>(); + + if (discoveryListEntity.getPic().size() > 0) { + + + for (int i = 0; i < discoveryListEntity.getPic().size(); i++) { + if (discoveryListEntity.getPic().get(i).endsWith(".mp4")) { + ImageInfo imageInfo = new ImageInfo(); + imageInfo.setType(2); + imageInfo.setBigImageUrl(discoveryListEntity.getPic().get(i)); + imageInfo.setThumbnailUrl(discoveryListEntity.getThumb()); + imageInfos.add(imageInfo); + } else { + ImageInfo imageInfo = new ImageInfo(); + imageInfo.setType(1); + imageInfo.setBigImageUrl(discoveryListEntity.getPic().get(i)); + imageInfo.setThumbnailUrl(discoveryListEntity.getPic().get(i)); + imageInfos.add(imageInfo); + } + + } + + } + homeGridAdapterItemBinding.nineGrid.setAdapter(new NineGridViewClickAdapter(getContext(), imageInfos)); + } + } + }); + mDataBinding.recyView.setAdapter(baseRecycleViewAdapter); + baseRecycleViewAdapter.setData(discoveryListEntities); + } + + private void addRecycleVerization(ArrayList lsit) { + BaseRecycleViewAdapter baseRecycleViewAdapter = (BaseRecycleViewAdapter) mDataBinding.recyView.getAdapter(); + + discoveryListEntities = lsit; + baseRecycleViewAdapter.setData(discoveryListEntities); + + } + + private void getGankList(String myurl, Map map, String msg, final int requstecode) { + progressDialog.setMessage(msg); + progressDialog.setCancelable(false); +// progressDialog.show(); + + mGankLoader = new Loader(); + Subscription subscription = mGankLoader.getMovie(myurl, map).subscribe(new Action1() { + + + @Override + public void call(Resultcode resultcode) { + + mDataBinding.rl.stopRefresh(true); + mDataBinding.rl.stopLoadMore(true); + progressDialog.dismiss(); + if (!(resultcode.status == 0)) { + baseActivity.setToast(1, resultcode.msg); + } + if (resultcode.status == 0) { + Gson gs = new Gson(); + LinkedTreeMap adta = (LinkedTreeMap) resultcode.data; + String s = gs.toJson(adta); + try { + + JSONObject jsonObject = new JSONObject(s); + org.json.JSONArray array = jsonObject.getJSONArray("info"); + Type type = new TypeToken>() { + }.getType(); + String fengmian = jsonObject.getString("fengmian"); + String avatar = jsonObject.getString("avatar"); + Picasso.with(getActivity()).load(fengmian) + .placeholder(R.mipmap.icon_default_rectangle) + .into(target); + Picasso.with(getActivity()).load(avatar) + .placeholder(R.mipmap.icon_default_rectangle) + .transform(new PicassoRoundTransform()) + .into(mDataBinding.head); + discoveryListEntities = new Gson().fromJson(array.toString(), type); + addRecycleVerization(discoveryListEntities); + + + } catch (Exception e) { + e.fillInStackTrace(); + } + } + +// if (resultcode.status == 0) { +//// baseActivity.setToast(0, resultcode.msg); +// if (requstecode == 0) { +// Gson gs = new Gson(); +// LinkedTreeMap adta = (LinkedTreeMap) resultcode.data; +// String s = gs.toJson(adta); +// +// ArrayList list = null; +// try { +// JSONObject jsonObject = new JSONObject(s); +// org.json.JSONArray array1 = jsonObject.getJSONArray("advert_info"); +// if (array1.length() > 0) { +// String img = array1.getJSONObject(0).optString("advert_img"); +// configTopImage(img); +// imgme = img; +// +// } +// org.json.JSONArray array = jsonObject.getJSONArray("advertorial_list"); +// Type type = new TypeToken>() { +// }.getType(); +// list = new Gson().fromJson(array.toString(), type); +// //addRecycleVerization(list); +// +// +// } catch (JSONException e) { +// e.printStackTrace(); +// } +// } +// } + + } + + + }, new Action1() { + @Override + public void call(Throwable throwable) { + progressDialog.dismiss(); + mDataBinding.rl.stopRefresh(true); + mDataBinding.rl.stopLoadMore(true); + baseActivity.setToast(2, getString(R.string.getdatafailure)); + throwable.printStackTrace(); + } + }); + + baseActivity.addSubscription(subscription); + } + + private Target target = new Target() { + @Override + public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { + Drawable drawable = new BitmapDrawable(bitmap); + mDataBinding.v.setBackground(drawable); + + + } + + @Override + public void onBitmapFailed(Drawable errorDrawable) { + } + + @Override + public void onPrepareLoad(Drawable placeHolderDrawable) { + } + }; + + public static DiscoveryFragment newInstance(String param1, String param2) { + DiscoveryFragment fragment = new DiscoveryFragment(); + Bundle args = new Bundle(); + args.putString(ARG_PARAM1, param1); + args.putString(ARG_PARAM2, param2); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + mParam1 = getArguments().getString(ARG_PARAM1); + mParam2 = getArguments().getString(ARG_PARAM2); + } + + } + +} diff --git a/app/src/main/java/entity/DiscoveryListEntity.java b/app/src/main/java/entity/DiscoveryListEntity.java new file mode 100644 index 0000000..de41694 --- /dev/null +++ b/app/src/main/java/entity/DiscoveryListEntity.java @@ -0,0 +1,196 @@ +package entity; + +import android.databinding.BaseObservable; + +import java.io.Serializable; +import java.util.ArrayList; + +public class DiscoveryListEntity extends BaseObservable implements Serializable { + private String goods_id; + private String userid; + private String goods_detail; + private ArrayList pic; + private String thumb; + private int type; + private String ctime; + private String avatar; + private String nickname; + private int is_like; + private ArrayList dis_content; + private ArrayList like; + + public String getGoods_id() { + return goods_id; + } + + public void setGoods_id(String goods_id) { + this.goods_id = goods_id; + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + + public String getGoods_detail() { + return goods_detail; + } + + public void setGoods_detail(String goods_detail) { + this.goods_detail = goods_detail; + } + + public ArrayList getPic() { + return pic; + } + + public void setPic(ArrayList pic) { + this.pic = pic; + } + + public String getThumb() { + return thumb; + } + + public void setThumb(String thumb) { + this.thumb = thumb; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getCtime() { + return ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public int getIs_like() { + return is_like; + } + + public void setIs_like(int is_like) { + this.is_like = is_like; + } + + public ArrayList getDis_content() { + return dis_content; + } + + public void setDis_content(ArrayList dis_content) { + this.dis_content = dis_content; + } + + public ArrayList getLike() { + return like; + } + + public void setLike(ArrayList like) { + this.like = like; + } + + public static class Dis_content extends BaseObservable implements Serializable { + + private String nickname; + private String from_id; + private String reply; + private String to_id; + private String contents; + private String dis_id; + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public String getFrom_id() { + return from_id; + } + + public void setFrom_id(String from_id) { + this.from_id = from_id; + } + + public String getReply() { + return reply; + } + + public void setReply(String reply) { + this.reply = reply; + } + + public String getTo_id() { + return to_id; + } + + public void setTo_id(String to_id) { + this.to_id = to_id; + } + + public String getContents() { + return contents; + } + + public void setContents(String contents) { + this.contents = contents; + } + + public String getDis_id() { + return dis_id; + } + + public void setDis_id(String dis_id) { + this.dis_id = dis_id; + } + } + + public static class Like extends BaseObservable implements Serializable { + private String nickname; + private String userid; + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + } +} diff --git a/app/src/main/java/http/RetrofitServiceManager.java b/app/src/main/java/http/RetrofitServiceManager.java index ffbbace..249e93e 100644 --- a/app/src/main/java/http/RetrofitServiceManager.java +++ b/app/src/main/java/http/RetrofitServiceManager.java @@ -4,6 +4,7 @@ package http; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; @@ -22,6 +23,7 @@ public class RetrofitServiceManager { builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS);//连接超时时间 builder.writeTimeout(DEFAULT_READ_TIME_OUT, TimeUnit.SECONDS);//写操作 超时时间 builder.readTimeout(DEFAULT_READ_TIME_OUT, TimeUnit.SECONDS);//读操作超时时间 + builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)); builder.retryOnConnectionFailure(true);//允许失败重试 // 添加公共参数拦截器 // String token= Config.getInstance(MyApplication.getApp().getBaseContext()).getString(ConfigValue.TOEKEN,""); diff --git a/app/src/main/java/imageselector/PreviewActivity.java b/app/src/main/java/imageselector/PreviewActivity.java index ba487ee..36f1ecb 100644 --- a/app/src/main/java/imageselector/PreviewActivity.java +++ b/app/src/main/java/imageselector/PreviewActivity.java @@ -77,7 +77,7 @@ public class PreviewActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_preview); + setContentView(R.layout.activity_preview2); setStatusBarVisible(true); mImages = tempImages; diff --git a/app/src/main/java/utils/NineImageLoader.java b/app/src/main/java/utils/NineImageLoader.java new file mode 100644 index 0000000..89eb76a --- /dev/null +++ b/app/src/main/java/utils/NineImageLoader.java @@ -0,0 +1,20 @@ +package utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.lzy.ninegrid.NineGridView; + +public class NineImageLoader implements NineGridView.ImageLoader { + @Override + public void onDisplayImage(Context context, ImageView imageView, String url) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public Bitmap getCacheImage(String url) { + return null; + } +} diff --git a/app/src/main/res/layout/activity_main_tab.xml b/app/src/main/res/layout/activity_main_tab.xml index 16ce282..78d62c8 100644 --- a/app/src/main/res/layout/activity_main_tab.xml +++ b/app/src/main/res/layout/activity_main_tab.xml @@ -60,10 +60,9 @@ android:gravity="center" android:drawableTop="@drawable/main_bottom_1" android:button="@null" - android:id="@+id/button1" android:textColor="@color/radiobuttoncolor" - android:text="@string/news1" + android:text="发现" android:layout_height="match_parent"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_f1recyclerview_vorization_item.xml b/app/src/main/res/layout/fragment_f1recyclerview_vorization_item.xml index 210e3eb..e5aee10 100644 --- a/app/src/main/res/layout/fragment_f1recyclerview_vorization_item.xml +++ b/app/src/main/res/layout/fragment_f1recyclerview_vorization_item.xml @@ -1,6 +1,6 @@ - + + @@ -12,65 +12,68 @@ + - - + android:orientation="vertical"> - - android:layout_marginEnd="10dip" - android:layout_marginLeft="5dip" - android:paddingLeft="10dip" - android:layout_marginRight="10dip" - android:layout_alignParentLeft="true" - android:textSize="14sp" + - android:layout_marginTop="25dip" - android:text="@{myentity.advertorial_title}" - android:textColor="@color/lightlittleGrey" - /> + + + + - - + android:background="@color/LightGray" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main1.xml b/app/src/main/res/layout/fragment_main1.xml index ecfc57a..cc2d58d 100644 --- a/app/src/main/res/layout/fragment_main1.xml +++ b/app/src/main/res/layout/fragment_main1.xml @@ -108,6 +108,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxhdpi/pl.png b/app/src/main/res/mipmap-xxhdpi/pl.png new file mode 100644 index 0000000..7879e79 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/pl.png differ diff --git a/app/src/test/java/com/sl/house_property/ExampleUnitTest.java b/app/src/test/java/com/sl/house_property/ExampleUnitTest.java deleted file mode 100644 index 06c5053..0000000 --- a/app/src/test/java/com/sl/house_property/ExampleUnitTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.sl.house_property; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - long timeM = 149; - long unitT = ((timeM - 30) / 60) + 1; - System.out.println("计费单位:" + unitT); - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/app/src/test/java/http/ProgressRequestBodyTest.java b/app/src/test/java/http/ProgressRequestBodyTest.java deleted file mode 100644 index 98b0f80..0000000 --- a/app/src/test/java/http/ProgressRequestBodyTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package http; - -public class ProgressRequestBodyTest { - -} \ No newline at end of file diff --git a/ninegridview/.gitignore b/ninegridview/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/ninegridview/.gitignore @@ -0,0 +1 @@ +/build diff --git a/ninegridview/build.gradle b/ninegridview/build.gradle new file mode 100644 index 0000000..2c25ff3 --- /dev/null +++ b/ninegridview/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'com.android.library' +android { + compileSdkVersion 27 + buildToolsVersion "27.0.3" + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 27 + + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + compile 'com.android.support:appcompat-v7:27.1.1' + compile 'com.android.support:support-annotations:27.1.1' + compile 'com.github.chrisbanes.photoview:library:1.2.4' + + + implementation files('../app/libs/pldroid-player-2.1.9.jar') + +} + +//apply from: '../bintray.gradle' \ No newline at end of file diff --git a/ninegridview/proguard-rules.pro b/ninegridview/proguard-rules.pro new file mode 100644 index 0000000..f727142 --- /dev/null +++ b/ninegridview/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in E:\Android\SDK/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/ninegridview/src/main/AndroidManifest.xml b/ninegridview/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b20dfd0 --- /dev/null +++ b/ninegridview/src/main/AndroidManifest.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/ImageInfo.java b/ninegridview/src/main/java/com/lzy/ninegrid/ImageInfo.java new file mode 100644 index 0000000..d6a416f --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/ImageInfo.java @@ -0,0 +1,91 @@ +package com.lzy.ninegrid; + +import java.io.Serializable; + +/** + * ================================================ + * 作 者:廖子尧 + * 版 本:1.0 + * 创建日期:2016/3/21 + * 描 述: + * 修订历史: + * ================================================ + */ +public class ImageInfo implements Serializable { + public String thumbnailUrl; + public String bigImageUrl; + public int imageViewHeight; + public int imageViewWidth; + public int imageViewX; + public int imageViewY; + public int type; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getThumbnailUrl() { + return thumbnailUrl; + } + + public void setThumbnailUrl(String thumbnailUrl) { + this.thumbnailUrl = thumbnailUrl; + } + + public String getBigImageUrl() { + return bigImageUrl; + } + + public void setBigImageUrl(String bigImageUrl) { + this.bigImageUrl = bigImageUrl; + } + + public int getImageViewHeight() { + return imageViewHeight; + } + + public void setImageViewHeight(int imageViewHeight) { + this.imageViewHeight = imageViewHeight; + } + + public int getImageViewWidth() { + return imageViewWidth; + } + + public void setImageViewWidth(int imageViewWidth) { + this.imageViewWidth = imageViewWidth; + } + + public int getImageViewX() { + return imageViewX; + } + + public void setImageViewX(int imageViewX) { + this.imageViewX = imageViewX; + } + + public int getImageViewY() { + return imageViewY; + } + + public void setImageViewY(int imageViewY) { + this.imageViewY = imageViewY; + } + + @Override + public String toString() { + return "ImageInfo{" + + "thumbnailUrl='" + thumbnailUrl + '\'' + + ", bigImageUrl='" + bigImageUrl + '\'' + + ", imageViewHeight=" + imageViewHeight + + ", imageViewWidth=" + imageViewWidth + + ", imageViewX=" + imageViewX + + ", imageViewY=" + imageViewY + + ", type=" + type + + '}'; + } +} diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/NineGridItemViewGroup.java b/ninegridview/src/main/java/com/lzy/ninegrid/NineGridItemViewGroup.java new file mode 100644 index 0000000..c8f2d62 --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/NineGridItemViewGroup.java @@ -0,0 +1,43 @@ +package com.lzy.ninegrid; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ImageView; + +import com.pili.pldroid.player.widget.PLVideoView; + + +public class NineGridItemViewGroup extends FrameLayout { + + private PLVideoView pv; + private ImageView iv; + + public NineGridItemViewGroup(@NonNull Context context) { + super(context); + } + + public NineGridItemViewGroup(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + LayoutInflater.from(context).inflate(R.layout.layout_item_ninegrid, this); + pv = findViewById(R.id.pv); + iv = findViewById(R.id.iv); + } + + public void setVisibleVideo() { + iv.setVisibility(View.GONE); + pv.setVisibility(View.VISIBLE); + } + + public void setImageVisible(ImageView.ScaleType type) { + pv.setVisibility(View.GONE); + iv.setVisibility(View.VISIBLE); + iv.setScaleType(type); + } + + +} diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/NineGridView.java b/ninegridview/src/main/java/com/lzy/ninegrid/NineGridView.java new file mode 100644 index 0000000..674a373 --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/NineGridView.java @@ -0,0 +1,240 @@ +package com.lzy.ninegrid; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.support.annotation.NonNull; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import java.util.ArrayList; +import java.util.List; + +public class NineGridView extends ViewGroup { + + public static final int MODE_FILL = 0; //填充模式,类似于微信 + public static final int MODE_GRID = 1; //网格模式,类似于QQ,4张图会 2X2布局 + + private static ImageLoader mImageLoader; //全局的图片加载器(必须设置,否者不显示图片) + + private int singleImageSize = 250; // 单张图片时的最大大小,单位dp + private float singleImageRatio = 1.0f; // 单张图片的宽高比(宽/高) + private int maxImageSize = 9; // 最大显示的图片数 + private int gridSpacing = 3; // 宫格间距,单位dp + private int mode = MODE_FILL; // 默认使用fill模式 + + private int columnCount; // 列数 + private int rowCount; // 行数 + private int gridWidth; // 宫格宽度 + private int gridHeight; // 宫格高度 + + private List imageViews; + private List mImageInfo; + private NineGridViewAdapter mAdapter; + + public NineGridView(Context context) { + this(context, null); + } + + public NineGridView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public NineGridView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + DisplayMetrics dm = context.getResources().getDisplayMetrics(); + gridSpacing = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gridSpacing, dm); + singleImageSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, singleImageSize, dm); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NineGridView); + gridSpacing = (int) a.getDimension(R.styleable.NineGridView_ngv_gridSpacing, gridSpacing); + singleImageSize = a.getDimensionPixelSize(R.styleable.NineGridView_ngv_singleImageSize, singleImageSize); + singleImageRatio = a.getFloat(R.styleable.NineGridView_ngv_singleImageRatio, singleImageRatio); + maxImageSize = a.getInt(R.styleable.NineGridView_ngv_maxSize, maxImageSize); + mode = a.getInt(R.styleable.NineGridView_ngv_mode, mode); + a.recycle(); + + imageViews = new ArrayList<>(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int width = MeasureSpec.getSize(widthMeasureSpec); + int height = 0; + int totalWidth = width - getPaddingLeft() - getPaddingRight(); + if (mImageInfo != null && mImageInfo.size() > 0) { + if (mImageInfo.size() == 1) { + gridWidth = singleImageSize > totalWidth ? totalWidth : singleImageSize; + gridHeight = (int) (gridWidth / singleImageRatio); + //矫正图片显示区域大小,不允许超过最大显示范围 + if (gridHeight > singleImageSize) { + float ratio = singleImageSize * 1.0f / gridHeight; + gridWidth = (int) (gridWidth * ratio); + gridHeight = singleImageSize; + } + } else { +// gridWidth = gridHeight = (totalWidth - gridSpacing * (columnCount - 1)) / columnCount; + //这里无论是几张图片,宽高都按总宽度的 1/3 + gridWidth = gridHeight = (totalWidth - gridSpacing * 2) / 3; + } + width = gridWidth * columnCount + gridSpacing * (columnCount - 1) + getPaddingLeft() + getPaddingRight(); + height = gridHeight * rowCount + gridSpacing * (rowCount - 1) + getPaddingTop() + getPaddingBottom(); + } + setMeasuredDimension(width, height); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + if (mImageInfo == null) return; + int childrenCount = mImageInfo.size(); + for (int i = 0; i < childrenCount; i++) { + ImageView childrenView = (ImageView) getChildAt(i); + + int rowNum = i / columnCount; + int columnNum = i % columnCount; + int left = (gridWidth + gridSpacing) * columnNum + getPaddingLeft(); + int top = (gridHeight + gridSpacing) * rowNum + getPaddingTop(); + int right = left + gridWidth; + int bottom = top + gridHeight; + childrenView.layout(left, top, right, bottom); + + if (mImageLoader != null) { + mImageLoader.onDisplayImage(getContext(), childrenView, mImageInfo.get(i).thumbnailUrl); + } + } + } + + /** 设置适配器 */ + public void setAdapter(@NonNull NineGridViewAdapter adapter) { + mAdapter = adapter; + List imageInfo = adapter.getImageInfo(); + + if (imageInfo == null || imageInfo.isEmpty()) { + setVisibility(GONE); + return; + } else { + setVisibility(VISIBLE); + } + + int imageCount = imageInfo.size(); + if (maxImageSize > 0 && imageCount > maxImageSize) { + imageInfo = imageInfo.subList(0, maxImageSize); + imageCount = imageInfo.size(); //再次获取图片数量 + } + + //默认是3列显示,行数根据图片的数量决定 + rowCount = imageCount / 3 + (imageCount % 3 == 0 ? 0 : 1); + columnCount = 3; + //grid模式下,显示4张使用2X2模式 + if (mode == MODE_GRID) { + if (imageCount == 4) { + rowCount = 2; + columnCount = 2; + } + } + + //保证View的复用,避免重复创建 + if (mImageInfo == null) { + for (int i = 0; i < imageCount; i++) { + ImageView iv = getImageView(i); + if (iv == null) return; + addView(iv, generateDefaultLayoutParams()); + } + } else { + int oldViewCount = mImageInfo.size(); + int newViewCount = imageCount; + if (oldViewCount > newViewCount) { + removeViews(newViewCount, oldViewCount - newViewCount); + } else if (oldViewCount < newViewCount) { + for (int i = oldViewCount; i < newViewCount; i++) { + ImageView iv = getImageView(i); + if (iv == null) return; + addView(iv, generateDefaultLayoutParams()); + } + } + } + //修改最后一个条目,决定是否显示更多 + if (adapter.getImageInfo().size() > maxImageSize) { + View child = getChildAt(maxImageSize - 1); + if (child instanceof NineGridViewWrapper) { + NineGridViewWrapper imageView = (NineGridViewWrapper) child; + imageView.setMoreNum(adapter.getImageInfo().size() - maxImageSize); + } + } + mImageInfo = imageInfo; + requestLayout(); + } + + /** 获得 ImageView 保证了 ImageView 的重用 */ + private ImageView getImageView(final int position) { + ImageView imageView; + if (position < imageViews.size()) { + imageView = imageViews.get(position); + } else { + imageView = mAdapter.generateImageView(getContext()); + imageView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mAdapter.onImageItemClick(getContext(), NineGridView.this, position, mAdapter.getImageInfo()); + } + }); + imageViews.add(imageView); + } + return imageView; + } + + /** 设置宫格间距 */ + public void setGridSpacing(int spacing) { + gridSpacing = spacing; + } + + /** 设置只有一张图片时的宽 */ + public void setSingleImageSize(int maxImageSize) { + singleImageSize = maxImageSize; + } + + /** 设置只有一张图片时的宽高比 */ + public void setSingleImageRatio(float ratio) { + singleImageRatio = ratio; + } + + /** 设置最大图片数 */ + public void setMaxSize(int maxSize) { + maxImageSize = maxSize; + } + + public int getMaxSize() { + return maxImageSize; + } + + public static void setImageLoader(ImageLoader imageLoader) { + mImageLoader = imageLoader; + } + + public static ImageLoader getImageLoader() { + return mImageLoader; + } + + public interface ImageLoader { + /** + * 需要子类实现该方法,以确定如何加载和显示图片 + * + * @param context 上下文 + * @param imageView 需要展示图片的ImageView + * @param url 图片地址 + */ + void onDisplayImage(Context context, ImageView imageView, String url); + + /** + * @param url 图片的地址 + * @return 当前框架的本地缓存图片 + */ + Bitmap getCacheImage(String url); + } +} diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/NineGridViewAdapter.java b/ninegridview/src/main/java/com/lzy/ninegrid/NineGridViewAdapter.java new file mode 100644 index 0000000..378aad9 --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/NineGridViewAdapter.java @@ -0,0 +1,51 @@ +package com.lzy.ninegrid; + +import android.content.Context; +import android.widget.ImageView; + +import java.io.Serializable; +import java.util.List; + +public abstract class NineGridViewAdapter implements Serializable { + + protected Context context; + private List imageInfo; + + public NineGridViewAdapter(Context context, List imageInfo) { + this.context = context; + this.imageInfo = imageInfo; + } + + /** + * 如果要实现图片点击的逻辑,重写此方法即可 + * + * @param context 上下文 + * @param nineGridView 九宫格控件 + * @param index 当前点击图片的的索引 + * @param imageInfo 图片地址的数据集合 + */ + protected void onImageItemClick(Context context, NineGridView nineGridView, int index, List imageInfo) { + } + + /** + * 生成ImageView容器的方式,默认使用NineGridImageViewWrapper类,即点击图片后,图片会有蒙板效果 + * 如果需要自定义图片展示效果,重写此方法即可 + * + * @param context 上下文 + * @return 生成的 ImageView + */ + protected ImageView generateImageView(Context context) { + NineGridViewWrapper imageView = new NineGridViewWrapper(context); + imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + imageView.setImageResource(R.drawable.ic_default_color); + return imageView; + } + + public List getImageInfo() { + return imageInfo; + } + + public void setImageInfoList(List imageInfo) { + this.imageInfo = imageInfo; + } +} \ No newline at end of file diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/NineGridViewWrapper.java b/ninegridview/src/main/java/com/lzy/ninegrid/NineGridViewWrapper.java new file mode 100644 index 0000000..c262aba --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/NineGridViewWrapper.java @@ -0,0 +1,137 @@ +package com.lzy.ninegrid; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.support.v4.view.ViewCompat; +import android.text.TextPaint; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.MotionEvent; +import android.widget.ImageView; + +public class NineGridViewWrapper extends ImageView { + + private int moreNum = 0; //显示更多的数量 + private int maskColor = 0x88000000; //默认的遮盖颜色 + private float textSize = 35; //显示文字的大小单位sp + private int textColor = 0xFFFFFFFF; //显示文字的颜色 + + private TextPaint textPaint; //文字的画笔 + private String msg = ""; //要绘制的文字 + + public NineGridViewWrapper(Context context) { + this(context, null); + } + + public NineGridViewWrapper(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public NineGridViewWrapper(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + //转化单位 + textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, textSize, getContext().getResources().getDisplayMetrics()); + + textPaint = new TextPaint(); + textPaint.setTextAlign(Paint.Align.CENTER); //文字居中对齐 + textPaint.setAntiAlias(true); //抗锯齿 + textPaint.setTextSize(textSize); //设置文字大小 + textPaint.setColor(textColor); //设置文字颜色 + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (moreNum > 0) { + canvas.drawColor(maskColor); + float baseY = getHeight() / 2 - (textPaint.ascent() + textPaint.descent()) / 2; + canvas.drawText(msg, getWidth() / 2, baseY, textPaint); + } + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + Drawable drawable = getDrawable(); + if (drawable != null) { + /** + * 默认情况下,所有的从同一资源(R.drawable.XXX)加载来的drawable实例都共享一个共用的状态, + * 如果你更改一个实例的状态,其他所有的实例都会收到相同的通知。 + * 使用使 mutate 可以让这个drawable变得状态不定。这个操作不能还原(变为不定后就不能变为原来的状态)。 + * 一个状态不定的drawable可以保证它不与其他任何一个drawabe共享它的状态。 + * 此处应该是要使用的 mutate(),但是在部分手机上会出现点击后变白的现象,所以没有使用 + * 目前这种解决方案没有问题 + */ +// drawable.mutate().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); + drawable.setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); + ViewCompat.postInvalidateOnAnimation(this); + } + break; + case MotionEvent.ACTION_MOVE: + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + Drawable drawableUp = getDrawable(); + if (drawableUp != null) { +// drawableUp.mutate().clearColorFilter(); + drawableUp.clearColorFilter(); + ViewCompat.postInvalidateOnAnimation(this); + } + break; + } + + return super.onTouchEvent(event); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + setImageDrawable(null); + } + + public int getMoreNum() { + return moreNum; + } + + public void setMoreNum(int moreNum) { + this.moreNum = moreNum; + msg = "+" + moreNum; + invalidate(); + } + + public int getMaskColor() { + return maskColor; + } + + public void setMaskColor(int maskColor) { + this.maskColor = maskColor; + invalidate(); + } + + public float getTextSize() { + return textSize; + } + + public void setTextSize(float textSize) { + this.textSize = textSize; + textPaint.setTextSize(textSize); + invalidate(); + } + + public int getTextColor() { + return textColor; + } + + public void setTextColor(int textColor) { + this.textColor = textColor; + textPaint.setColor(textColor); + invalidate(); + } +} \ No newline at end of file diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/preview/HackyViewPager.java b/ninegridview/src/main/java/com/lzy/ninegrid/preview/HackyViewPager.java new file mode 100644 index 0000000..d88409a --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/preview/HackyViewPager.java @@ -0,0 +1,38 @@ +package com.lzy.ninegrid.preview; + +import android.content.Context; +import android.support.v4.view.ViewPager; +import android.util.AttributeSet; +import android.view.MotionEvent; + +/** 修复图片在ViewPager控件中缩放报错的BUG */ +public class HackyViewPager extends ViewPager { + + public HackyViewPager(Context context) { + super(context); + } + + public HackyViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + try { + return super.onTouchEvent(ev); + } catch (IllegalArgumentException ex) { + ex.printStackTrace(); + } + return false; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + try { + return super.onInterceptTouchEvent(ev); + } catch (IllegalArgumentException ex) { + ex.printStackTrace(); + } + return false; + } +} diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/preview/ImagePreviewActivity.java b/ninegridview/src/main/java/com/lzy/ninegrid/preview/ImagePreviewActivity.java new file mode 100644 index 0000000..d143c9b --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/preview/ImagePreviewActivity.java @@ -0,0 +1,238 @@ +package com.lzy.ninegrid.preview; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.app.Activity; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.support.v4.view.ViewPager; +import android.util.DisplayMetrics; +import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.lzy.ninegrid.ImageInfo; +import com.lzy.ninegrid.R; + +import java.util.List; + +public class ImagePreviewActivity extends Activity implements ViewTreeObserver.OnPreDrawListener { + + public static final String IMAGE_INFO = "IMAGE_INFO"; + public static final String CURRENT_ITEM = "CURRENT_ITEM"; + public static final int ANIMATE_DURATION = 200; + + private RelativeLayout rootView; + + private ImagePreviewAdapter imagePreviewAdapter; + private List imageInfo; + private int currentItem; + private int imageHeight; + private int imageWidth; + private int screenWidth; + private int screenHeight; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_preview2); + + ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager2); + final TextView tv_pager = (TextView) findViewById(R.id.tv_pager); + rootView = (RelativeLayout) findViewById(R.id.rootView); + + DisplayMetrics metric = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(metric); + screenWidth = metric.widthPixels; + screenHeight = metric.heightPixels; + + Intent intent = getIntent(); + imageInfo = (List) intent.getSerializableExtra(IMAGE_INFO); + currentItem = intent.getIntExtra(CURRENT_ITEM, 0); + + imagePreviewAdapter = new ImagePreviewAdapter(this, imageInfo); + viewPager.setAdapter(imagePreviewAdapter); + viewPager.setCurrentItem(currentItem); + viewPager.getViewTreeObserver().addOnPreDrawListener(this); + viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + currentItem = position; + tv_pager.setText(String.format(getString(R.string.select2), currentItem + 1, imageInfo.size())); + } + }); + tv_pager.setText(String.format(getString(R.string.select2), currentItem + 1, imageInfo.size())); + } + + @Override + public void onBackPressed() { + + finishActivityAnim(); + } + + /** 绘制前开始动画 */ + @Override + public boolean onPreDraw() { + rootView.getViewTreeObserver().removeOnPreDrawListener(this); + final View view = imagePreviewAdapter.getPrimaryItem(); + final ImageView imageView = imagePreviewAdapter.getPrimaryImageView(); + computeImageWidthAndHeight(imageView); + + final ImageInfo imageData = imageInfo.get(currentItem); + final float vx = imageData.imageViewWidth * 1.0f / imageWidth; + final float vy = imageData.imageViewHeight * 1.0f / imageHeight; + ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1.0f); + valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + long duration = animation.getDuration(); + long playTime = animation.getCurrentPlayTime(); + float fraction = duration > 0 ? (float) playTime / duration : 1f; + if (fraction > 1) fraction = 1; + view.setTranslationX(evaluateInt(fraction, imageData.imageViewX + imageData.imageViewWidth / 2 - imageView.getWidth() / 2, 0)); + view.setTranslationY(evaluateInt(fraction, imageData.imageViewY + imageData.imageViewHeight / 2 - imageView.getHeight() / 2, 0)); + view.setScaleX(evaluateFloat(fraction, vx, 1)); + view.setScaleY(evaluateFloat(fraction, vy, 1)); + view.setAlpha(fraction); + rootView.setBackgroundColor(evaluateArgb(fraction, Color.TRANSPARENT, Color.BLACK)); + } + }); + addIntoListener(valueAnimator); + valueAnimator.setDuration(ANIMATE_DURATION); + valueAnimator.start(); + return true; + } + + /** activity的退场动画 */ + public void finishActivityAnim() { + final View view = imagePreviewAdapter.getPrimaryItem(); + final ImageView imageView = imagePreviewAdapter.getPrimaryImageView(); + computeImageWidthAndHeight(imageView); + + final ImageInfo imageData = imageInfo.get(currentItem); + final float vx = imageData.imageViewWidth * 1.0f / imageWidth; + final float vy = imageData.imageViewHeight * 1.0f / imageHeight; + final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1.0f); + valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + long duration = animation.getDuration(); + long playTime = animation.getCurrentPlayTime(); + float fraction = duration > 0 ? (float) playTime / duration : 1f; + if (fraction > 1) fraction = 1; + view.setTranslationX(evaluateInt(fraction, 0, imageData.imageViewX + imageData.imageViewWidth / 2 - imageView.getWidth() / 2)); + view.setTranslationY(evaluateInt(fraction, 0, imageData.imageViewY + imageData.imageViewHeight / 2 - imageView.getHeight() / 2)); + view.setScaleX(evaluateFloat(fraction, 1, vx)); + view.setScaleY(evaluateFloat(fraction, 1, vy)); + view.setAlpha(1 - fraction); + rootView.setBackgroundColor(evaluateArgb(fraction, Color.BLACK, Color.TRANSPARENT)); + } + }); + addOutListener(valueAnimator); + valueAnimator.setDuration(ANIMATE_DURATION); + valueAnimator.start(); + } + + /** 计算图片的宽高 */ + private void computeImageWidthAndHeight(ImageView imageView) { + + // 获取真实大小 + try { + Drawable drawable = imageView.getDrawable(); + int intrinsicHeight = drawable.getIntrinsicHeight(); + int intrinsicWidth = drawable.getIntrinsicWidth(); + // 计算出与屏幕的比例,用于比较以宽的比例为准还是高的比例为准,因为很多时候不是高度没充满,就是宽度没充满 + float h = screenHeight * 1.0f / intrinsicHeight; + float w = screenWidth * 1.0f / intrinsicWidth; + if (h > w) h = w; + else w = h; + + // 得出当宽高至少有一个充满的时候图片对应的宽高 + imageHeight = (int) (intrinsicHeight * h); + imageWidth = (int) (intrinsicWidth * w); + }catch (Exception e){ + + } + + } + + /** 进场动画过程监听 */ + private void addIntoListener(ValueAnimator valueAnimator) { + valueAnimator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + rootView.setBackgroundColor(0x0); + } + + @Override + public void onAnimationEnd(Animator animation) { + } + + @Override + public void onAnimationCancel(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + }); + } + + /** 退场动画过程监听 */ + private void addOutListener(ValueAnimator valueAnimator) { + valueAnimator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + rootView.setBackgroundColor(0x0); + } + + @Override + public void onAnimationEnd(Animator animation) { + finish(); + overridePendingTransition(0, 0); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + }); + } + + /** Integer 估值器 */ + public Integer evaluateInt(float fraction, Integer startValue, Integer endValue) { + int startInt = startValue; + return (int) (startInt + fraction * (endValue - startInt)); + } + + /** Float 估值器 */ + public Float evaluateFloat(float fraction, Number startValue, Number endValue) { + float startFloat = startValue.floatValue(); + return startFloat + fraction * (endValue.floatValue() - startFloat); + } + + /** Argb 估值器 */ + public int evaluateArgb(float fraction, int startValue, int endValue) { + int startA = (startValue >> 24) & 0xff; + int startR = (startValue >> 16) & 0xff; + int startG = (startValue >> 8) & 0xff; + int startB = startValue & 0xff; + + int endA = (endValue >> 24) & 0xff; + int endR = (endValue >> 16) & 0xff; + int endG = (endValue >> 8) & 0xff; + int endB = endValue & 0xff; + + return (startA + (int) (fraction * (endA - startA))) << 24// + | (startR + (int) (fraction * (endR - startR))) << 16// + | (startG + (int) (fraction * (endG - startG))) << 8// + | (startB + (int) (fraction * (endB - startB))); + } +} diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/preview/ImagePreviewAdapter.java b/ninegridview/src/main/java/com/lzy/ninegrid/preview/ImagePreviewAdapter.java new file mode 100644 index 0000000..422dbfc --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/preview/ImagePreviewAdapter.java @@ -0,0 +1,128 @@ +package com.lzy.ninegrid.preview; + +import android.content.Context; +import android.graphics.Bitmap; +import android.support.annotation.NonNull; +import android.support.v4.view.PagerAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; + +import com.lzy.ninegrid.ImageInfo; +import com.lzy.ninegrid.NineGridView; +import com.lzy.ninegrid.R; + +import java.util.List; + +import uk.co.senab.photoview.PhotoView; +import uk.co.senab.photoview.PhotoViewAttacher; + +/** + * ================================================ + * 作 者:廖子尧 + * 版 本:1.0 + * 创建日期:2016/3/21 + * 描 述: + * 修订历史: + * ================================================ + */ +public class ImagePreviewAdapter extends PagerAdapter implements PhotoViewAttacher.OnPhotoTapListener { + + private List imageInfo; + private Context context; + private View currentView; + + public ImagePreviewAdapter(Context context, @NonNull List imageInfo) { + super(); + this.imageInfo = imageInfo; + this.context = context; + } + + @Override + public int getCount() { + return imageInfo.size(); + } + + @Override + public boolean isViewFromObject(View view, Object object) { + return view == object; + } + + @Override + public void setPrimaryItem(ViewGroup container, int position, Object object) { + super.setPrimaryItem(container, position, object); + currentView = (View) object; + } + + public View getPrimaryItem() { + return currentView; + } + + public ImageView getPrimaryImageView() { + return (ImageView) currentView.findViewById(R.id.pv); + } + + @Override + public Object instantiateItem(ViewGroup container, int position) { + View view = LayoutInflater.from(context).inflate(R.layout.item_photoview, container, false); + + final ProgressBar pb = (ProgressBar) view.findViewById(R.id.pb); + final PhotoView imageView = (PhotoView) view.findViewById(R.id.pv); + + ImageInfo info = this.imageInfo.get(position); + imageView.setOnPhotoTapListener(this); + showExcessPic(info, imageView); + + //如果需要加载的loading,需要自己改写,不能使用这个方法 + NineGridView.getImageLoader().onDisplayImage(view.getContext(), imageView, info.bigImageUrl); + +// pb.setVisibility(View.VISIBLE); +// Glide.with(context).load(info.bigImageUrl)// +// .placeholder(R.drawable.ic_default_image)// +// .error(R.drawable.ic_default_image)// +// .diskCacheStrategy(DiskCacheStrategy.ALL)// +// .listener(new RequestListener() { +// @Override +// public boolean onException(Exception e, String model, Target target, boolean isFirstResource) { +// pb.setVisibility(View.GONE); +// return false; +// } +// +// @Override +// public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { +// pb.setVisibility(View.GONE); +// return false; +// } +// }).into(imageView); + + container.addView(view); + return view; + } + + /** 展示过度图片 */ + private void showExcessPic(ImageInfo imageInfo, PhotoView imageView) { + //先获取大图的缓存图片 + Bitmap cacheImage = NineGridView.getImageLoader().getCacheImage(imageInfo.bigImageUrl); + //如果大图的缓存不存在,在获取小图的缓存 + if (cacheImage == null) cacheImage = NineGridView.getImageLoader().getCacheImage(imageInfo.thumbnailUrl); + //如果没有任何缓存,使用默认图片,否者使用缓存 + if (cacheImage == null) { + imageView.setImageResource(R.drawable.ic_default_color); + } else { + imageView.setImageBitmap(cacheImage); + } + } + + @Override + public void destroyItem(ViewGroup container, int position, Object object) { + container.removeView((View) object); + } + + /** 单击屏幕关闭 */ + @Override + public void onPhotoTap(View view, float x, float y) { + ((ImagePreviewActivity) context).finishActivityAnim(); + } +} \ No newline at end of file diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/preview/MediaController.java b/ninegridview/src/main/java/com/lzy/ninegrid/preview/MediaController.java new file mode 100644 index 0000000..cd0b512 --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/preview/MediaController.java @@ -0,0 +1,601 @@ +package com.lzy.ninegrid.preview; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Rect; +import android.media.AudioManager; +import android.os.Build; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.PopupWindow; +import android.widget.ProgressBar; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.pili.pldroid.player.IMediaController; + +import java.util.Locale; + +/** + * You can write a custom MediaController instead of this class + * A MediaController widget must implement all the interface defined by com.pili.pldroid.player.IMediaController + */ +public class MediaController extends FrameLayout implements IMediaController { + + private static final String TAG = "PLMediaController"; + private IMediaController.MediaPlayerControl mPlayer; + private Context mContext; + private PopupWindow mWindow; + private int mAnimStyle; + private View mAnchor; + private View mRoot; + private ProgressBar mProgress; + private TextView mEndTime, mCurrentTime; + private long mDuration; + private boolean mShowing; + private boolean mDragging; + private boolean mInstantSeeking = true; + private long mSeekPosition = 0l; + private static int sDefaultTimeout = 3000; + private static final int SEEK_TO_POST_DELAY_MILLIS = 200; + + private static final int FADE_OUT = 1; + private static final int SHOW_PROGRESS = 2; + private boolean mFromXml = false; + private ImageButton mPauseButton; + private ImageButton mFfwdButton; + private ImageButton mRewButton; + private ImageButton mNextButton; + private ImageButton mPrevButton; + + private boolean mUseFastForward; + + private static final int IC_MEDIA_PAUSE_ID = Resources.getSystem().getIdentifier("ic_media_pause", "drawable", "android"); + private static final int IC_MEDIA_PLAY_ID = Resources.getSystem().getIdentifier("ic_media_play", "drawable", "android"); + private static final int MEDIA_CONTROLLER_ID = Resources.getSystem().getIdentifier("media_controller", "layout", "android"); + private static final int PRV_BUTTON_ID = Resources.getSystem().getIdentifier("prev", "id", "android"); + private static final int FFWD_BUTTON_ID = Resources.getSystem().getIdentifier("ffwd", "id", "android"); + private static final int NEXT_BUTTON_ID = Resources.getSystem().getIdentifier("next", "id", "android"); + private static final int REW_BUTTON_ID = Resources.getSystem().getIdentifier("rew", "id", "android"); + private static final int PAUSE_BUTTON_ID = Resources.getSystem().getIdentifier("pause", "id", "android"); + private static final int MEDIACONTROLLER_PROGRESS_ID = Resources.getSystem().getIdentifier("mediacontroller_progress", "id", "android"); + private static final int END_TIME_ID = Resources.getSystem().getIdentifier("time", "id", "android"); + private static final int CURRENT_TIME_ID = Resources.getSystem().getIdentifier("time_current", "id", "android"); + + private AudioManager mAM; + private Runnable mLastSeekBarRunnable; + private boolean mDisableProgress = false; + private OnClickSpeedAdjustListener mOnClickSpeedAdjustListener; + + public interface OnClickSpeedAdjustListener { + void onClickNormal(); + void onClickFaster(); + void onClickSlower(); + } + + public MediaController(Context context, AttributeSet attrs) { + super(context, attrs); + mRoot = this; + mFromXml = true; + initController(context); + } + + public MediaController(Context context) { + super(context); + if (!mFromXml && initController(context)) + initFloatingWindow(); + } + + public MediaController(Context context, boolean useFastForward, boolean disableProgressBar) { + this(context); + mUseFastForward = useFastForward; + mDisableProgress = disableProgressBar; + } + + public MediaController(Context context, boolean useFastForward) { + this(context); + mUseFastForward = useFastForward; + } + + public void refreshProgress() { + mProgress.setProgress(1000); + mCurrentTime.setText(generateTime(mDuration)); + } + + public void setOnClickSpeedAdjustListener(OnClickSpeedAdjustListener listener) { + mOnClickSpeedAdjustListener = listener; + } + + private boolean initController(Context context) { + mUseFastForward = true; + mContext = context.getApplicationContext(); + mAM = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + return true; + } + + @Override + public void onFinishInflate() { + if (mRoot != null) + initControllerView(mRoot); + super.onFinishInflate(); + } + + private void initFloatingWindow() { + mWindow = new PopupWindow(mContext); + mWindow.setFocusable(false); + mWindow.setBackgroundDrawable(null); + mWindow.setOutsideTouchable(true); + mAnimStyle = android.R.style.Animation; + } + + /** + * Create the view that holds the widgets that control playback. Derived + * classes can override this to create their own. + * + * @return The controller view. + */ + protected View makeControllerView() { + return ((LayoutInflater) mContext + .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(MEDIA_CONTROLLER_ID, this); + } + + private void initControllerView(View v) { + // By default these are hidden. + mPrevButton = (ImageButton) v.findViewById(PRV_BUTTON_ID); + if (mPrevButton != null) { + mPrevButton.setVisibility(View.GONE); + } + mNextButton = (ImageButton) v.findViewById(NEXT_BUTTON_ID); + if (mNextButton != null) { + mNextButton.setVisibility(View.GONE); + } + + mFfwdButton = (ImageButton) v.findViewById(FFWD_BUTTON_ID); + if (mFfwdButton != null) { + mFfwdButton.setOnClickListener(mFfwdListener); + if (!mFromXml) { + mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); + } + } + + mRewButton = (ImageButton) v.findViewById(REW_BUTTON_ID); + if (mRewButton != null) { + mRewButton.setOnClickListener(mRewListener); + if (!mFromXml) { + mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); + } + } + mPauseButton = (ImageButton) v.findViewById(PAUSE_BUTTON_ID); + if (mPauseButton != null) { + mPauseButton.requestFocus(); + mPauseButton.setOnClickListener(mPauseListener); + } + + mProgress = (ProgressBar) v.findViewById(MEDIACONTROLLER_PROGRESS_ID); + if (mProgress != null) { + if (mProgress instanceof SeekBar) { + SeekBar seeker = (SeekBar) mProgress; + seeker.setOnSeekBarChangeListener(mSeekListener); + seeker.setThumbOffset(1); + } + mProgress.setMax(1000); + mProgress.setEnabled(!mDisableProgress); + } + + mEndTime = (TextView) v.findViewById(END_TIME_ID); + mCurrentTime = (TextView) v.findViewById(CURRENT_TIME_ID); + } + + /** + * Control the action when the seekbar dragged by user + * + * @param seekWhenDragging + * True the media will seek periodically + */ + public void setInstantSeeking(boolean seekWhenDragging) { + mInstantSeeking = seekWhenDragging; + } + + private void disableUnsupportedButtons() { + try { + if (mPauseButton != null && !mPlayer.canPause()) + mPauseButton.setEnabled(false); + } catch (IncompatibleClassChangeError ex) { + } + } + + /** + *

+ * Change the animation style resource for this controller. + *

+ * + *

+ * If the controller is showing, calling this method will take effect only + * the next time the controller is shown. + *

+ * + * @param animationStyle + * animation style to use when the controller appears and disappears. + * Set to -1 for the default animation, 0 for no animation, + * or a resource identifier for an explicit animation. + * + */ + public void setAnimationStyle(int animationStyle) { + mAnimStyle = animationStyle; + } + + + public interface OnShownListener { + public void onShown(); + } + + private OnShownListener mShownListener; + + public void setOnShownListener(OnShownListener l) { + mShownListener = l; + } + + public interface OnHiddenListener { + public void onHidden(); + } + + private OnHiddenListener mHiddenListener; + + public void setOnHiddenListener(OnHiddenListener l) { + mHiddenListener = l; + } + + @SuppressLint("HandlerLeak") + private Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + long pos; + switch (msg.what) { + case FADE_OUT: + hide(); + break; + case SHOW_PROGRESS: + if (!mPlayer.isPlaying()) { + return; + } + pos = setProgress(); + if (pos == -1) { + return; + } + if (!mDragging && mShowing) { + msg = obtainMessage(SHOW_PROGRESS); + sendMessageDelayed(msg, 50); + updatePausePlay(); + } + break; + } + } + }; + + private long setProgress() { + if (mPlayer == null || mDragging) { + return 0; + } + + long position = mPlayer.getCurrentPosition(); + long duration = mPlayer.getDuration(); + if (mProgress != null) { + if (duration > 0) { + long pos = 1000L * position / duration; + mProgress.setProgress((int) pos); + } + int percent = mPlayer.getBufferPercentage(); + mProgress.setSecondaryProgress(percent * 10); + } + + mDuration = duration; + + if (mEndTime != null) + mEndTime.setText(generateTime(mDuration)); + if (mCurrentTime != null) + mCurrentTime.setText(generateTime(position)); + + return position; + } + + private static String generateTime(long position) { + int totalSeconds = (int) (position / 1000); + + int seconds = totalSeconds % 60; + int minutes = (totalSeconds / 60) % 60; + int hours = totalSeconds / 3600; + + if (hours > 0) { + return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes, + seconds).toString(); + } else { + return String.format(Locale.US, "%02d:%02d", minutes, seconds) + .toString(); + } + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + show(sDefaultTimeout); + return true; + } + + @Override + public boolean onTrackballEvent(MotionEvent ev) { + show(sDefaultTimeout); + return false; + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + int keyCode = event.getKeyCode(); + if (event.getRepeatCount() == 0 + && (keyCode == KeyEvent.KEYCODE_HEADSETHOOK + || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode == KeyEvent.KEYCODE_SPACE)) { + doPauseResume(); + show(sDefaultTimeout); + if (mPauseButton != null) + mPauseButton.requestFocus(); + return true; + } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) { + if (mPlayer.isPlaying()) { + mPlayer.pause(); + updatePausePlay(); + } + return true; + } else if (keyCode == KeyEvent.KEYCODE_BACK + || keyCode == KeyEvent.KEYCODE_MENU) { + hide(); + return true; + } else { + show(sDefaultTimeout); + } + return super.dispatchKeyEvent(event); + } + + private OnClickListener mPauseListener = new OnClickListener() { + public void onClick(View v) { + if (mOnClickSpeedAdjustListener != null) { + mOnClickSpeedAdjustListener.onClickNormal(); + } + doPauseResume(); + show(sDefaultTimeout); + } + }; + + private void updatePausePlay() { + if (mRoot == null || mPauseButton == null) + return; + + if (mPlayer.isPlaying()) + mPauseButton.setImageResource(IC_MEDIA_PAUSE_ID); + else + mPauseButton.setImageResource(IC_MEDIA_PLAY_ID); + } + + private void doPauseResume() { + if (mPlayer.isPlaying()) + mPlayer.pause(); + else + mPlayer.start(); + updatePausePlay(); + } + + private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() { + + public void onStartTrackingTouch(SeekBar bar) { + mDragging = true; + show(3600000); + mHandler.removeMessages(SHOW_PROGRESS); + if (mInstantSeeking) + mAM.setStreamMute(AudioManager.STREAM_MUSIC, true); + } + + public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { + if (!fromuser) { + return; + } + + + final long newposition = (long) (mDuration * progress) / 1000; + String time = generateTime(newposition); + if (mInstantSeeking) { + mHandler.removeCallbacks(mLastSeekBarRunnable); + mLastSeekBarRunnable = new Runnable() { + @Override + public void run() { + mPlayer.seekTo(newposition); + } + }; + mHandler.postDelayed(mLastSeekBarRunnable, SEEK_TO_POST_DELAY_MILLIS); + } + if (mCurrentTime != null) + mCurrentTime.setText(time); + } + + public void onStopTrackingTouch(SeekBar bar) { + if (!mInstantSeeking) + mPlayer.seekTo(mDuration * bar.getProgress() / 1000); + + show(sDefaultTimeout); + mHandler.removeMessages(SHOW_PROGRESS); + mAM.setStreamMute(AudioManager.STREAM_MUSIC, false); + mDragging = false; + mHandler.sendEmptyMessageDelayed(SHOW_PROGRESS, 1000); + } + }; + + private OnClickListener mRewListener = new OnClickListener() { + public void onClick(View v) { + if (mOnClickSpeedAdjustListener != null) { + mOnClickSpeedAdjustListener.onClickSlower(); + } + show(sDefaultTimeout); + } + }; + + private OnClickListener mFfwdListener = new OnClickListener() { + public void onClick(View v) { + if (mOnClickSpeedAdjustListener != null) { + mOnClickSpeedAdjustListener.onClickFaster(); + } + show(sDefaultTimeout); + } + }; + + /** + * Set the view that acts as the anchor for the control view. + * + * - This can for example be a VideoView, or your Activity's main view. + * - AudioPlayer has no anchor view, so the view parameter will be null. + * + * @param view + * The view to which to anchor the controller when it is visible. + */ + @Override + public void setAnchorView(View view) { + mAnchor = view; + if (mAnchor == null) { + sDefaultTimeout = 0; // show forever + } + if (!mFromXml) { + removeAllViews(); + mRoot = makeControllerView(); + mWindow.setContentView(mRoot); + mWindow.setWidth(LayoutParams.MATCH_PARENT); + mWindow.setHeight(LayoutParams.WRAP_CONTENT); + } + initControllerView(mRoot); + } + + @Override + public void setMediaPlayer(MediaPlayerControl player) { + mPlayer = player; + updatePausePlay(); + } + + @Override + public void show() { + show(sDefaultTimeout); + } + + /** + * Show the controller on screen. It will go away automatically after + * 'timeout' milliseconds of inactivity. + * + * @param timeout + * The timeout in milliseconds. Use 0 to show the controller until hide() is called. + */ + @Override + public void show(int timeout) { + if (!mShowing) { + if (mAnchor != null && mAnchor.getWindowToken() != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + mAnchor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + } + } + if (mPauseButton != null) + mPauseButton.requestFocus(); + disableUnsupportedButtons(); + + if (mFromXml) { + setVisibility(View.VISIBLE); + } else { + int[] location = new int[2]; + + if (mAnchor != null) { + mAnchor.getLocationOnScreen(location); + Rect anchorRect = new Rect(location[0], location[1], + location[0] + mAnchor.getWidth(), location[1] + + mAnchor.getHeight()); + + mWindow.setAnimationStyle(mAnimStyle); + mWindow.showAtLocation(mAnchor, Gravity.BOTTOM, + anchorRect.left, 0); + } else { + Rect anchorRect = new Rect(location[0], location[1], + location[0] + mRoot.getWidth(), location[1] + + mRoot.getHeight()); + + mWindow.setAnimationStyle(mAnimStyle); + mWindow.showAtLocation(mRoot, Gravity.BOTTOM, + anchorRect.left, 0); + } + } + mShowing = true; + if (mShownListener != null) + mShownListener.onShown(); + } + updatePausePlay(); + mHandler.sendEmptyMessage(SHOW_PROGRESS); + + if (timeout != 0) { + mHandler.removeMessages(FADE_OUT); + mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT), + timeout); + } + } + + @Override + public boolean isShowing() { + return mShowing; + } + + @Override + public void hide() { + if (mShowing) { + if (mAnchor != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + //mAnchor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); + } + } + try { + mHandler.removeMessages(SHOW_PROGRESS); + if (mFromXml) + setVisibility(View.GONE); + else + mWindow.dismiss(); + } catch (IllegalArgumentException ex) { + Log.d(TAG, "MediaController already removed"); + } + mShowing = false; + if (mHiddenListener != null) + mHiddenListener.onHidden(); + } + } + + @Override + public void setEnabled(boolean enabled) { + if (mPauseButton != null) { + mPauseButton.setEnabled(enabled); + } + if (mFfwdButton != null) { + mFfwdButton.setEnabled(enabled); + } + if (mRewButton != null) { + mRewButton.setEnabled(enabled); + } + if (mProgress != null && !mDisableProgress) + mProgress.setEnabled(enabled); + disableUnsupportedButtons(); + super.setEnabled(enabled); + } + + public PopupWindow getWindow() { + return mWindow; + } + + public long getSeekPosition() { + return mSeekPosition; + } +} diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/preview/NineGridViewClickAdapter.java b/ninegridview/src/main/java/com/lzy/ninegrid/preview/NineGridViewClickAdapter.java new file mode 100644 index 0000000..292ddd4 --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/preview/NineGridViewClickAdapter.java @@ -0,0 +1,85 @@ +package com.lzy.ninegrid.preview; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; + +import com.lzy.ninegrid.ImageInfo; +import com.lzy.ninegrid.NineGridView; +import com.lzy.ninegrid.NineGridViewAdapter; + +import java.io.Serializable; +import java.util.List; + +/** + * ================================================ + * 作 者:廖子尧 + * 版 本:1.0 + * 创建日期:2016/3/21 + * 描 述: + * 修订历史: + * ================================================ + */ +public class NineGridViewClickAdapter extends NineGridViewAdapter { + + private int statusHeight; + + public NineGridViewClickAdapter(Context context, List imageInfo) { + super(context, imageInfo); + statusHeight = getStatusHeight(context); + } + + @Override + protected void onImageItemClick(Context context, NineGridView nineGridView, int index, List imageInfo) { + if (imageInfo.get(index).type == 2) { + Intent intent = new Intent(context, VideoPreviewActivity.class); + intent.putExtra("url", imageInfo.get(index).bigImageUrl); + context.startActivity(intent); + }else { + for (int i = 0; i < imageInfo.size(); i++) { + ImageInfo info = imageInfo.get(i); + View imageView; + if (i < nineGridView.getMaxSize()) { + imageView = nineGridView.getChildAt(i); + } else { + //如果图片的数量大于显示的数量,则超过部分的返回动画统一退回到最后一个图片的位置 + imageView = nineGridView.getChildAt(nineGridView.getMaxSize() - 1); + } + info.imageViewWidth = imageView.getWidth(); + info.imageViewHeight = imageView.getHeight(); + int[] points = new int[2]; + imageView.getLocationInWindow(points); + info.imageViewX = points[0]; + info.imageViewY = points[1] - statusHeight; + } + + Intent intent = new Intent(context, ImagePreviewActivity.class); + Bundle bundle = new Bundle(); + bundle.putSerializable(ImagePreviewActivity.IMAGE_INFO, (Serializable) imageInfo); + bundle.putInt(ImagePreviewActivity.CURRENT_ITEM, index); + intent.putExtras(bundle); + context.startActivity(intent); + ((Activity) context).overridePendingTransition(0, 0); + + } + + } + + /** + * 获得状态栏的高度 + */ + public int getStatusHeight(Context context) { + int statusHeight = -1; + try { + Class clazz = Class.forName("com.android.internal.R$dimen"); + Object object = clazz.newInstance(); + int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString()); + statusHeight = context.getResources().getDimensionPixelSize(height); + } catch (Exception e) { + e.printStackTrace(); + } + return statusHeight; + } +} diff --git a/ninegridview/src/main/java/com/lzy/ninegrid/preview/VideoPreviewActivity.java b/ninegridview/src/main/java/com/lzy/ninegrid/preview/VideoPreviewActivity.java new file mode 100644 index 0000000..c84c953 --- /dev/null +++ b/ninegridview/src/main/java/com/lzy/ninegrid/preview/VideoPreviewActivity.java @@ -0,0 +1,44 @@ +package com.lzy.ninegrid.preview; + +import android.app.Activity; +import android.os.Bundle; +import android.support.annotation.Nullable; + +import com.lzy.ninegrid.R; +import com.pili.pldroid.player.widget.PLVideoView; + +public class VideoPreviewActivity extends Activity { + + private PLVideoView pLVideoView; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_preview_video); + pLVideoView = findViewById(R.id.pLVideoView); + String url = getIntent().getStringExtra("url"); + pLVideoView.setVideoPath(url); + MediaController mMediaController = new MediaController(this); + pLVideoView.setMediaController(mMediaController); + pLVideoView.start(); + } + + @Override + protected void onResume() { + super.onResume(); + pLVideoView.start(); + } + + @Override + protected void onPause() { + super.onPause(); + pLVideoView.pause(); + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + pLVideoView.stopPlayback(); + } +} diff --git a/ninegridview/src/main/res/drawable/ic_default_color.xml b/ninegridview/src/main/res/drawable/ic_default_color.xml new file mode 100644 index 0000000..173d436 --- /dev/null +++ b/ninegridview/src/main/res/drawable/ic_default_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ninegridview/src/main/res/layout/activity_preview2.xml b/ninegridview/src/main/res/layout/activity_preview2.xml new file mode 100644 index 0000000..88b4683 --- /dev/null +++ b/ninegridview/src/main/res/layout/activity_preview2.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/ninegridview/src/main/res/layout/activity_preview_video.xml b/ninegridview/src/main/res/layout/activity_preview_video.xml new file mode 100644 index 0000000..cbde2ca --- /dev/null +++ b/ninegridview/src/main/res/layout/activity_preview_video.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/ninegridview/src/main/res/layout/item_photoview.xml b/ninegridview/src/main/res/layout/item_photoview.xml new file mode 100644 index 0000000..546fc3a --- /dev/null +++ b/ninegridview/src/main/res/layout/item_photoview.xml @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/ninegridview/src/main/res/layout/layout_item_ninegrid.xml b/ninegridview/src/main/res/layout/layout_item_ninegrid.xml new file mode 100644 index 0000000..0647a8a --- /dev/null +++ b/ninegridview/src/main/res/layout/layout_item_ninegrid.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/ninegridview/src/main/res/values/attrs.xml b/ninegridview/src/main/res/values/attrs.xml new file mode 100644 index 0000000..eb3a84f --- /dev/null +++ b/ninegridview/src/main/res/values/attrs.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/ninegridview/src/main/res/values/colors.xml b/ninegridview/src/main/res/values/colors.xml new file mode 100644 index 0000000..78b6e9b --- /dev/null +++ b/ninegridview/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #33000000 + \ No newline at end of file diff --git a/ninegridview/src/main/res/values/strings.xml b/ninegridview/src/main/res/values/strings.xml new file mode 100644 index 0000000..ef3e652 --- /dev/null +++ b/ninegridview/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + %1$s/%2$s + \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index e7b4def..cb7838f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app' +include ':app',':ninegridview'