要求:
1、MVP分包分层:Model、View、Presenter三层
2、Okhttp二次封装,OkhttpClient使用单例模式封装并封装GET、POST请求方法
3、 使用Universal-Image-Loader或Glide图片加载框架
4、属性动画完成图一翻牌的效果,图片自定义,定义动画时间为3秒钟,动画结束后自动跳转到图二界面
5、集成Umeng第三方登录功能,并实现QQ登录,登录成功后显示用户信息
6、使用RecyclerView显示数据并设置点击事件,点击后跳转到图四界面并使用WebView显示页面内容,点击分享按钮,使用Umeng分享功能,成功把该页面的链接分享到QQ朋友圈
----------------------------------------------------代码--------------------------------------------- 有盟第三方登陆和分享还要导入依赖,架包 ,图片和布局。。。。。。
清单文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.slx.slx4_5"> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:name=".application.MyApplication"> <activity android:name=".view.MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".view.WelcomActivity" /> <activity android:name=".view.DataActivity" > </activity> <activity android:name=".view.WebActivity"></activity> <activity android:name="com.umeng.socialize.media.WBShareCallBackActivity" android:configChanges="keyboardHidden|orientation" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:exported="false" android:screenOrientation="portrait" > </activity> <activity android:name="com.sina.weibo.sdk.web.WeiboSdkWebActivity" android:configChanges="keyboardHidden|orientation" android:exported="false" android:windowSoftInputMode="adjustResize" > </activity> <activity android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" android:launchMode="singleTask" android:name="com.sina.weibo.sdk.share.WbShareTransActivity"> <intent-filter> <action android:name="com.sina.weibo.sdk.action.ACTION_SDK_REQ_ACTIVITY" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <activity android:name=".wxapi.WXEntryActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:exported="true" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <activity android:name="com.tencent.tauth.AuthActivity" android:launchMode="singleTask" android:noHistory="true" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="tencent100424468" /> </intent-filter> </activity> <activity android:name="com.tencent.connect.common.AssistActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:configChanges="orientation|keyboardHidden|screenSize"/> </application> </manifest>
依赖:
compile 'com.squareup.okhttp3:okhttp:3.10.0' compile 'com.android.support:recyclerview-v7:26.1.0' //Gson依赖 compile 'com.google.code.gson:gson:2.2.4' // Glide网络访问图片的依赖: compile 'com.github.bumptech.glide:glide:3.7.0' implementation files('libs/umeng-common-1.5.0.jar')
1.动画页面
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.slx.slx4_5.view.MainActivity" > <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@mipmap/a" android:id="@+id/image1"/> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@mipmap/b" android:id="@+id/image2"/> </FrameLayout>
package com.example.slx.slx4_5.view; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import com.example.slx.slx4_5.R; public class MainActivity extends AppCompatActivity { private ImageView image1; private ImageView image2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image1 = findViewById(R.id.image1); image2 = findViewById(R.id.image2); showImage1();//图片1可见 ObjectAnimator animator1 = ObjectAnimator.ofFloat(image1, "rotationY", 0f, 90f); final ObjectAnimator animator2 = ObjectAnimator.ofFloat(image2, "rotationY", 270f, 360f); animator1.setDuration(2000); animator2.setDuration(2000); animator1.start(); animator1.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); showImage2(); animator2.start(); } }); animator2.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); Intent intent = new Intent(MainActivity.this, WelcomActivity.class); startActivity(intent); } }); } private void showImage1() { //图片1可见 image1.setVisibility(View.VISIBLE); //图片2可见 image2.setVisibility(View.INVISIBLE); } private void showImage2() { //图片2可见 image2.setVisibility(View.VISIBLE); //图片1可见 image1.setVisibility(View.INVISIBLE); } }
2.第三方欢迎页面
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.slx.slx4_5.view.WelcomActivity"> <Button android:id="@+id/login" android:layout_width="match_parent" android:layout_height="40dp" android:text="QQ登陆"/> <TextView android:id="@+id/text" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:layout_gravity="center" android:layout_width="100dp" android:layout_height="100dp" android:id="@+id/img"/> <Button android:id="@+id/but" android:text="跳转" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
package com.example.slx.slx4_5.view; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.bumptech.glide.Glide; import com.example.slx.slx4_5.R; import com.umeng.socialize.UMAuthListener; import com.umeng.socialize.UMShareAPI; import com.umeng.socialize.bean.SHARE_MEDIA; import java.util.Map; public class WelcomActivity extends AppCompatActivity { private ImageView img; private TextView tv; private Button login; private UMAuthListener authListener; private Button but; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_welcom); img = findViewById(R.id.img); tv = findViewById(R.id.text); //qq登陆按钮 login = findViewById(R.id.login); //跳转的按钮 but = findViewById(R.id.but); but.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(WelcomActivity.this,DataActivity.class); startActivity(intent); } }); //qq登陆按钮点击事件 login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { UMShareAPI umShareAPI = UMShareAPI.get(WelcomActivity.this); umShareAPI.getPlatformInfo(WelcomActivity.this, SHARE_MEDIA.QQ, authListener); } }); authListener = new UMAuthListener() { /** * @desc 授权开始的回调 * @param platform 平台名称 */ @Override public void onStart(SHARE_MEDIA platform) { } /** * @desc 授权成功的回调 * @param platform 平台名称 * @param action 行为序号,开发者用不上 * @param data 用户资料返回 */ @Override public void onComplete(SHARE_MEDIA platform, int action, Map<String, String> data) { Toast.makeText(WelcomActivity.this, "成功了"+data.get("name"), Toast.LENGTH_LONG).show(); tv.setText(data.get("name")); Glide.with(WelcomActivity.this).load(data.get("iconurl")).into(img); } /** * @desc 授权失败的回调 * @param platform 平台名称 * @param action 行为序号,开发者用不上 * @param t 错误原因 */ @Override public void onError(SHARE_MEDIA platform, int action, Throwable t) { Toast.makeText(WelcomActivity.this, "失败:" + t.getMessage(), Toast.LENGTH_LONG).show(); } /** * @desc 授权取消的回调 * @param platform 平台名称 * @param action 行为序号,开发者用不上 */ @Override public void onCancel(SHARE_MEDIA platform, int action) { Toast.makeText(WelcomActivity.this, "取消了", Toast.LENGTH_LONG).show(); } }; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data); } }
3.请求数据页面
工具类
package com.example.slx.slx4_5.utils; import android.os.Environment; import java.io.File; import java.util.Map; import java.util.concurrent.TimeUnit; import okhttp3.Cache; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; /** * Created by Administrator on 2018/3/8. */ public class OkhtttpUtils { //单例模式,把构造方法进行私有化 // private OkhtttpUtils(){}; static OkHttpClient client; public static OkHttpClient getInstance(){ if (client==null) { //更加安全 synchronized (OkhtttpUtils.class) { //缓存的地方 mnt/sdcard File file = new File(Environment.getExternalStorageDirectory(), "cache11"); client = new OkHttpClient().newBuilder() .readTimeout(3000, TimeUnit.SECONDS) //设置读取超时时间 .connectTimeout(3000, TimeUnit.SECONDS) //设置连接的超时时间 .cache(new Cache(file, 10 * 1024)) .build(); } } return client; } /** * get请求 * Callback 是一个接口 */ public static void doGet(String url, Callback callback){ //1:拿到okhttpclient 对像 OkHttpClient client = getInstance(); //2:进行请求的操作 Request request = new Request.Builder() .url(url) .build(); client.newCall(request).enqueue(callback); } //post请求 /** * * @param url 请求的地址 * @param parms 请求的参数 * @param callback callback */ public static void doPost(String url, Map<String,String> parms,Callback callback){ //得到客户端的对像 OkHttpClient client = getInstance(); //不是FormBody,而是一个Builder FormBody.Builder body = new FormBody.Builder(); //key value for (String key:parms.keySet()){ //value的值 body.add(key,parms.get(key)); } Request request = new Request.Builder() .url(url) .post(body.build()) .build(); client.newCall(request).enqueue(callback); } //用来上传图片的 //url , 图片 ,参数 Callback public static void upImage(String url,File file,String filenName,Map<String,String> params,Callback callback){ OkHttpClient client = getInstance(); //requestBody的实现类 Formbody MultipartBody.Builder builder = new MultipartBody.Builder(); if (params!=null){ for (String key :params.keySet()){ builder.addFormDataPart(key,params.get(key)); } } //设置类型 builder.setType(MultipartBody.FORM); builder.addFormDataPart("file",filenName,RequestBody.create(MediaType.parse("application/octet-stream"),file)); // builder.setType(MultipartBody.FORM); // builder.addFormDataPart("file",filenName,RequestBody.create(MediaType.parse("application/octet-stream"),file)); //builder.addFormDataPart("file","aa.png",builder.build()); Request request = new Request.Builder() .url(url) .post(builder.build()) .build(); client.newCall(request).enqueue(callback); } }
总布局
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.slx.slx4_5.view.DataActivity"> <android.support.v7.widget.RecyclerView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/rcv"> </android.support.v7.widget.RecyclerView> </android.support.constraint.ConstraintLayout>
条目布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="100dp" android:layout_height="100dp" android:id="@+id/img"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/text" android:text="hhhh"/> </LinearLayout>
view层
package com.example.slx.slx4_5.view; import com.example.slx.slx4_5.model.data.Data; import java.util.List; /** * Created by lenovo on 2018/4/5. */ public interface Iview { void toBackHome(List<Data.NewslistBean> list); }
package com.example.slx.slx4_5.view; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import com.example.slx.slx4_5.R; import com.example.slx.slx4_5.adapter.MyAdapter; import com.example.slx.slx4_5.model.data.Data; import com.example.slx.slx4_5.persenter.MyPersenter; import java.util.List; public class DataActivity extends AppCompatActivity implements Iview ,MyAdapter.ItemListerer { String dataUrl="http://api.tianapi.com/startup/?key=71e58b5b2f930eaf1f937407acde08fe&num=10"; private List<Data.NewslistBean> list; @SuppressLint("HandlerLeak") Handler handler=new Handler(){ private MyAdapter myAdapter; @Override public void handleMessage(Message msg) { super.handleMessage(msg); list = (List<Data.NewslistBean>)msg.obj; myAdapter = new MyAdapter(DataActivity.this,list); myAdapter.setDataListerer(DataActivity.this); rcv.setAdapter(myAdapter); } }; private RecyclerView rcv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_data); rcv = findViewById(R.id.rcv); rcv.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)); MyPersenter myPersenter = new MyPersenter(this); myPersenter.netWork(dataUrl); } @Override public void toBackHome(List<Data.NewslistBean> list) { Message message = Message.obtain(); message.obj=list; handler.sendMessage(message); } @Override public void onItemClick(int position) { Intent intent = new Intent(DataActivity.this, WebActivity.class); intent.putExtra("url",list.get(position).getUrl()); startActivity(intent); } }
p层
package com.example.slx.slx4_5.persenter; import com.example.slx.slx4_5.model.data.Data; import java.util.List; /** * Created by lenovo on 2018/4/5. */ public interface IPersenter { void netWork(String dataUrl); void success(List<Data.NewslistBean> list); void error(); }
package com.example.slx.slx4_5.persenter; import com.example.slx.slx4_5.model.MyModel; import com.example.slx.slx4_5.model.data.Data; import com.example.slx.slx4_5.view.Iview; import java.util.List; /** * Created by lenovo on 2018/4/5. */ public class MyPersenter implements IPersenter{ Iview iview; private final MyModel myModel; public MyPersenter(Iview iview){ this.iview=iview; myModel = new MyModel(); } @Override public void netWork(String dataUrl) { myModel.getData(dataUrl,this); } @Override public void success(List<Data.NewslistBean> list) { iview.toBackHome(list); } @Override public void error() { } }
m层
package com.example.slx.slx4_5.model; import com.example.slx.slx4_5.persenter.IPersenter; /** * Created by lenovo on 2018/4/5. */ public interface Imodel { void getData(String dataUrl, IPersenter iPersenter); }
package com.example.slx.slx4_5.model; import com.example.slx.slx4_5.model.data.Data; import com.example.slx.slx4_5.persenter.IPersenter; import com.example.slx.slx4_5.utils.OkhtttpUtils; import com.google.gson.Gson; import java.io.IOException; import java.util.List; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Response; /** * Created by lenovo on 2018/4/5. */ public class MyModel implements Imodel{ @Override public void getData(String dataUrl, final IPersenter iPersenter) { OkhtttpUtils.doGet(dataUrl, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { String json = response.body().string(); Gson gson = new Gson(); Data data = gson.fromJson(json, Data.class); List<Data.NewslistBean> list = data.getNewslist(); iPersenter.success(list); } }); } }
适配器
package com.example.slx.slx4_5.adapter; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import com.example.slx.slx4_5.R; import com.example.slx.slx4_5.model.data.Data; import java.util.List; /** * Created by lenovo on 2018/4/5. */ public class MyAdapter extends RecyclerView.Adapter{ //2.定义一个接口对象 private ItemListerer itemListerer; private Context context; private List<Data.NewslistBean> list; private ViewHolder viewHolder; public MyAdapter(Context context, List<Data.NewslistBean> list) { this.context = context; this.list = list; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = View.inflate(parent.getContext(), R.layout.itemlayout, null); viewHolder = new ViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { final ViewHolder viewHolder=(ViewHolder)holder; viewHolder.textView.setText(list.get(position).getTitle()); Glide.with(context).load(list.get(position).getPicUrl()).into(viewHolder.imageView); //6.触发事件 viewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int position1 = viewHolder.getLayoutPosition(); //5.设置触发事件 itemListerer.onItemClick(position1); } }); } @Override public int getItemCount() { return list.size(); } class ViewHolder extends RecyclerView.ViewHolder { private TextView textView; private ImageView imageView; public ViewHolder(View view) { super(view); textView = view.findViewById(R.id.text); imageView = view.findViewById(R.id.img); } } //1.定义一个接口 public interface ItemListerer{ void onItemClick(int position); }; //3.给接口定义一个赋值的方法 public void setDataListerer(ItemListerer itemListerer){ this.itemListerer=itemListerer; } }
4.分享页面
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.slx.slx4_5.view.WebActivity"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/fxbut" android:text="分享"/> <WebView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/webView"> </WebView> </LinearLayout>
package com.example.slx.slx4_5.view; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; import android.widget.Toast; import com.example.slx.slx4_5.R; import com.umeng.socialize.ShareAction; import com.umeng.socialize.UMShareListener; import com.umeng.socialize.bean.SHARE_MEDIA; import com.umeng.socialize.media.UMWeb; public class WebActivity extends AppCompatActivity { private Button fxbut; private WebView webView; private UMShareListener shareListener; private String url; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web); Intent intent = getIntent(); url = intent.getStringExtra("url"); fxbut = findViewById(R.id.fxbut); webView = findViewById(R.id.webView); webView.loadUrl(url); fxbut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { UMWeb web = new UMWeb(url); web.setTitle("我是网址");//标题 web.setDescription("这是一个网址");//描述 new ShareAction(WebActivity.this) .withMedia(web) .setDisplayList(SHARE_MEDIA.SINA,SHARE_MEDIA.QQ,SHARE_MEDIA.WEIXIN) .setCallback(shareListener).open(); } }); shareListener = new UMShareListener() { /** * @descrption 分享开始的回调 * @param platform 平台类型 */ @Override public void onStart(SHARE_MEDIA platform) { } /** * @descrption 分享成功的回调 * @param platform 平台类型 */ @Override public void onResult(SHARE_MEDIA platform) { Toast.makeText(WebActivity.this,"成功 了",Toast.LENGTH_LONG).show(); } /** * @descrption 分享失败的回调 * @param platform 平台类型 * @param t 错误原因 */ @Override public void onError(SHARE_MEDIA platform, Throwable t) { Toast.makeText(WebActivity.this,"失 败"+t.getMessage(),Toast.LENGTH_LONG).show(); } /** * @descrption 分享取消的回调 * @param platform 平台类型 */ @Override public void onCancel(SHARE_MEDIA platform) { Toast.makeText(WebActivity.this,"取消 了",Toast.LENGTH_LONG).show(); } }; //设置不用系统浏览器打开,直接显示在当前Webview webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); } }
mapplication: package com.example.slx.slx4_5.application; import android.app.Application; import com.umeng.commonsdk.UMConfigure; import com.umeng.socialize.PlatformConfig; /** * Created by lenovo on 2018/4/5. */ public class MyApplication extends Application{ //三方的key { PlatformConfig.setWeixin("wx967daebe835fbeac","5bb696d9ccd75a38c8a0bfe0675559b3"); PlatformConfig.setQQZone("100424468", "c7394704798a158208a74ab60104f0ba"); PlatformConfig.setSinaWeibo("3921700954", "04b48b094faeb16683c32669824ebdad","http://sns.whalecloud.com"); } @Override public void onCreate() { super.onCreate(); UMConfigure.init(this,"5a12384aa40fa3551f0001d1" ,"umeng",UMConfigure.DEVICE_TYPE_PHONE,"");//58edcfeb310c93091c000be2 5965ee00734be40b580001a0 } }
package com.example.slx.slx4_5.wxapi; import com.umeng.socialize.weixin.view.WXCallbackActivity; /** * Created by lenovo on 2018/4/5. */ public class WXEntryActivity extends WXCallbackActivity { }