TabLayout + ViewPager + Fragment + Retrofit + Fresco + NDK + AIDL + WebView

效果图:

导入依赖

compile 'com.android.support:design:26.0.0-alpha1'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.facebook.fresco:fresco:1.5.0'

页面:

     activity_mian.xml

<?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="bw.com.week3_test.MainActivity">

  <android.support.design.widget.TabLayout
      android:layout_width="match_parent"
      android:layout_height="60dp"
      android:id="@+id/tab_layout_id"
      />

    <android.support.v4.view.ViewPager
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/view_pager_id"
        />

</LinearLayout>

my_fragment01.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="bw.com.week3_test.demo01.MyFragment01">


    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rv_id"/>

</FrameLayout>

my_fragment02.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="bw.com.week3_test.demo02.MyFragment02">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名"
        android:id="@+id/name_et_id"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入密码"
        android:id="@+id/pwd_et_id"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入验证码 1234"
        android:id="@+id/code_et_id"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="登录"
        android:id="@+id/but_id"
        />


</LinearLayout>


my_fragment03.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="bw.com.week3_test.demo03.MyFragment03">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/tv_id"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>


my_fragment04.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="bw.com.week3_test.demo04.MyFragment04">

    <!-- TODO: Update blank fragment layout -->
    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/web_view_id"/>

</FrameLayout>

item_rv.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.facebook.drawee.view.SimpleDraweeView
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:id="@+id/sdv_id"
        fresco:roundedCornerRadius="5dp"
        fresco:roundTopLeft="true"
        fresco:roundTopRight="true"
        fresco:roundBottomLeft="true"
        fresco:roundBottomRight="true"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv_id"
        android:text="标题"
        android:layout_marginTop="10dp"
        android:textSize="20sp"
        />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="@color/colorAccent"
        android:layout_margin="10dp"/>

</LinearLayout>

MyApp.java

public class MyApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        //初始化Fresco
        Fresco.initialize(this);
    }
}


清单文件:

<uses-permission android:name="android.permission.INTERNET"/>

<application
    android:name=".MyApp"

MainActivity.java


public class MainActivity extends AppCompatActivity {

    private TabLayout mTabLayout;//导航
    private List<String> titles = new ArrayList<>();//所有的标题

    private ViewPager mViewPager;//视图页面
    private List<Fragment> data = new ArrayList<>();//数据源
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTabLayout = (TabLayout) findViewById(R.id.tab_layout_id);
        mViewPager = (ViewPager) findViewById(R.id.view_pager_id);

        //构建标题
        titles.add("获取数据");
        titles.add("NDK 登录");
        titles.add("AIDL");
        titles.add("加载网页");

        //构建数据源
        data.add(new MyFragment01());
        data.add(new MyFragment02());
        data.add(new MyFragment03());
        data.add(new MyFragment04());

        //定义适配器
        adapter = new MyAdapter(getSupportFragmentManager());

        //设置适配器
        mViewPager.setAdapter(adapter);

        //将tabLayout 和ViewPager 结合在一起
        mTabLayout.setupWithViewPager(mViewPager);

    }
    //自定义适配器
    class MyAdapter extends FragmentPagerAdapter
    {

        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return data.get(position);
        }

        @Override
        public int getCount() {
            return data.size();
        }

        //返回当前对应的标题

        @Override
        public CharSequence getPageTitle(int position) {
            return titles.get(position);
        }
    }
}

第一个Fragment 


MyFragment01.java


/**
 * 通过Retrofit 获取网络数据, 展示在RecycleView 中, 图片用Fresco 加载, 图片圆角处理
 * 通过Retrofit :
 *           导入依赖
 *          1, 接口  @GET()
 *                  Call<实体类> getInfo();
 *          2, 实体类
 *          3, MyFragment  --  7小步骤
 *          
 *    Fresco 使用
 *          1, 导入依赖
 *          2, 必须初始化 -- MyApp
 *          3, 在布局页面中 , 使用控件
 *          4, 在代码中, 加载图片
 */
public class MyFragment01 extends Fragment {


    private RecyclerView mRv;//控件
    private List<VMoiver.DataBean> data;//数据源  -- 网络获取
    private MyRecycleViewAdapter adapter;//适配器


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.my_fragment01, container, false);

        mRv = (RecyclerView) view.findViewById(R.id.rv_id);

        //设置显示模式
        LinearLayoutManager manager = new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false);

        mRv.setLayoutManager(manager);

        //Retrofit 执行的步骤
        //1, 得到构建者
        Retrofit.Builder builder = new Retrofit.Builder();

        //2, 设置基础地址
        builder.baseUrl("http://app.vmoiver.com/apiv3/post/");

        //3, 设置gson 解析
        builder.addConverterFactory(GsonConverterFactory.create());

        //4, 得到Retrofit对象
        Retrofit retrofit = builder.build();

        //5, 通过Retrofit得到接口
        VMoiverInterface vMoiverInterface = retrofit.create(VMoiverInterface.class);

        //6, 得到Call 对象
        Call<VMoiver> call = vMoiverInterface.getInfo();

        //7, 异步请求数据
        call.enqueue(new Callback<VMoiver>() {
            @Override
            public void onResponse(Call<VMoiver> call, Response<VMoiver> response) {

                VMoiver vMoiver = response.body();

                //得到数据源
                data = vMoiver.getData();

                adapter = new MyRecycleViewAdapter(getContext(),data);

                mRv.setAdapter(adapter);
            }

            @Override
            public void onFailure(Call<VMoiver> call, Throwable t) {

            }
        });
        return view;
    }

}

VMoiver.java --- GsonFromant 生成的实体类


VMoiverInterface.java

public interface VMoiverInterface {

    //http://app.vmoiver.com/apiv3/post/  ----   getPostInCate?cateid=0&p=1
    @GET("getPostInCate?cateid=0&p=1")
    Call<VMoiver> getInfo();

}

MyRecycleViewAdapter.java

public class MyRecycleViewAdapter extends RecyclerView.Adapter<MyRecycleViewAdapter.ViewHolder> {

    private Context context;
    private List<VMoiver.DataBean> data;

    public MyRecycleViewAdapter(Context context, List<VMoiver.DataBean> data)
    {
        this.context = context;
        this.data = data;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(context).inflate(R.layout.item_rv,parent,false);

        ViewHolder viewHolder = new ViewHolder(view);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        //加载图片
        Uri uri = Uri.parse(data.get(position).getImage());
        holder.sdv.setImageURI(uri);

        //设置标题
        holder.tv.setText(data.get(position).getTitle());
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder
    {

        SimpleDraweeView sdv;
        TextView tv;

        public ViewHolder(View itemView) {

            super(itemView);

            this.sdv = (SimpleDraweeView) itemView.findViewById(R.id.sdv_id);
            this.tv = (TextView) itemView.findViewById(R.id.tv_id);
        }
    }
}

第二个Fragment   -- NDK 实现登陆

    1,  配置ndk 的环境, 参考网址:    http://blog.csdn.net/xiuxiu_861223/article/details/78792939

    2,  创建 JinTest.java

       

public class JniTest {

//********************导入依赖库***********************
    static {

        System.loadLibrary("app");
    }

    private static  Context context;

    public JniTest(Context context)
    {
        this.context = context;
    }

    //登录的方法  -- java  调用 C
    public static native   String login(String uName, String uPwd,int code);

    //登录成功的信息   -- C 调用Java
    //javah -d jni -classpath ../../build/intermediates/classes/debug bw.com.week3_test.demo02.JniTest
    public static void showMessage(String message)
    {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
    }
}

   3, 点击菜单栏的Make Module 'app'即可


 4, 生成头文件(*.h

    首先打开工具栏的Terminal工具,使用cd命令定位到Moduel appmain目录

    执行:  红色的文字是需要根据自己的Jni 改变的

javah -d jni -classpath ../../build/intermediates/classes/debug bw.com.week3_test.demo02.JniTest

   5, 创建  :bw_com_week3_test_demo02_JniTest.c

   

#include "bw_com_week3_test_demo02_JniTest.h"
JNIEXPORT jstring JNICALL Java_bw_com_week3_1test_demo02_JniTest_login
  (JNIEnv *env, jclass jobj, jstring juName, jstring juPwd, jint jcode)
    {
           const char* resultMessage;//声明字符变量
          jclass jc;

          //1, 加载java 类中的class 对象
          jc = (*env)->FindClass(env, "bw/com/week3_test/demo02/JniTest");//反射机制来获取对象
          //jc = (*env)->GetObjectClass(env, jobj);//使用GetObjectClass函数来获取class对象:

         //2, 获取java 类的方法
         //2.1 获取java 类的方法  --- 得到静态的方法
         jmethodID showMessageID = (*env)->GetStaticMethodID(env,jc,"showMessage","(Ljava/lang/String;)V");
         //查看验证码是否正确
         if(jcode==1234)
         {
              const char* cstr;
              jboolean isCopy;

              cstr = (*env)->GetStringUTFChars(env,juName,&isCopy);
              int result = strcmp(cstr,"admin");
              if(result==0)
              {
                  resultMessage = "login success";
                 // 2.2  通过方法的id , 回调java 的代码
                (*env)->CallStaticVoidMethod(env,jc,showMessageID,resultMessage);

              }else
              {
                   resultMessage = "login Error";
                 // 2.2  通过方法的id , 回调java 的代码
                (*env)->CallStaticVoidMethod(env,jc,showMessageID,resultMessage);
              }
         }
         else
         {
              resultMessage = "code Error";
            // 2.2  通过方法的id , 回调java 的代码
           (*env)->CallStaticVoidMethod(env,jc,showMessageID,resultMessage);
         }

       return  resultMessage;
    }

 6,准备就绪,开始构建.so文件  -- 点击菜单栏的Make Module 'app'即可


  7,使用so库。在JniTest.java中添加代码

static {    

System.loadLibrary("app"); 

}


       8,  MyFragment02.java

/**
 * NDK 实现登录
 */
public class MyFragment02 extends Fragment implements View.OnClickListener {
    
    private EditText name_et_id;
    private EditText pwd_et_id;
    private EditText code_et_id;
    private Button but_id;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.my_fragment02, container, false);

        initView(view);

        return view;
    }

    private void initView(View view) {
        name_et_id = (EditText) view.findViewById(R.id.name_et_id);
        pwd_et_id = (EditText) view.findViewById(R.id.pwd_et_id);
        code_et_id = (EditText) view.findViewById(R.id.code_et_id);
        but_id = (Button) view.findViewById(R.id.but_id);

        but_id.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        JniTest jniTest = new JniTest(getContext());
        int code = Integer.parseInt(code_et_id.getText().toString());
        jniTest.login(name_et_id.getText().toString(),pwd_et_id.getText().toString(),code);

    }
}



第三个Fragment  --  AIDL 获取服务器中数据库的内容


  1, 创建服务器的 App  --  >  名称为 Server


1.1  在src/mian 中创建 aidl 文件

DataAidl.aidl

interface DataAidl {

   String getDbInfo();
}

1.2  编译工程, 生成同名的DataAidl.java文件


1.3  创建数据库的帮助类

DbOpenHelper.java

public class DbOpenHelper  extends SQLiteOpenHelper{


    public DbOpenHelper(Context context) {
        super(context, "bw1511A.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL("create table if not exists user(_id integer primary key autoincrement,name varchar(20),age integer)");

        db.execSQL("insert into user(name,age) values('abc',12)");
        db.execSQL("insert into user(name,age) values('bcd',22)");
        db.execSQL("insert into user(name,age) values('cde',33)");
        db.execSQL("insert into user(name,age) values('def',34)");
        db.execSQL("insert into user(name,age) values('efg',45)");
        db.execSQL("insert into user(name,age) values('fgh',55)");
        db.execSQL("insert into user(name,age) values('ghi',65)");
        db.execSQL("insert into user(name,age) values('hig',43)");
        db.execSQL("insert into user(name,age) values('igk',32)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

   1.4   创建服务器  --- MyService.java

public class MyService extends Service {
    DataAidl.Stub stub = new DataAidl.Stub() {
        @Override
        public String getDbInfo() throws RemoteException {

            DbOpenHelper dbOpenHelper = new DbOpenHelper(MyService.this);

            SQLiteDatabase db = dbOpenHelper.getReadableDatabase();

            Cursor cursor = db.rawQuery("select * from user",null);

            StringBuilder stringBuilder = new StringBuilder();

            while (cursor.moveToNext())
            {
                String name = cursor.getString(cursor.getColumnIndex("name"));
                int age  = cursor.getInt(cursor.getColumnIndex("age"));

                stringBuilder.append("姓名:  "+name).append("  ,   ").append("年龄: " + age).append("\n");
            }

            return stringBuilder.toString();
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return stub;
    }
}

1.5  在清单文件中注册Service

<service android:name=".MyService">
    <intent-filter>
        <action android:name="com.bw.aidl"/>
    </intent-filter>
</service>


2, 在客户端的App 中 -- App工程的第三个Fragment


将服务端的src/main中的aidl 文件夹, 复制到客户端的 src/main 文件夹中,编译工程


MyFragment03.java

/**
 *
 * 通过AIDL 获取服务器中, 数据库的所有内容
 *
 * AIDL   实现跨进程间的通信
 *
 *         Server :
 *
 *              1, 数据库
 *              2, Service  -- 注册 -- action
 *              3, AIDL
 *         
 *         Client   :
 *
 *               1, 绑定服务
 *               2, 复制服务器中的AIDL文件
 *               3, 通过AIDL 获取数据
 */
public class MyFragment03 extends Fragment {


    private DataAidl dataAidl;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            dataAidl = DataAidl.Stub.asInterface(service);

            try {

                String result =  dataAidl.getDbInfo();

                mTv.setText(result);


            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    private TextView mTv;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
       View view =  inflater.inflate(R.layout.my_fragment03, container, false);

        mTv = (TextView) view.findViewById(R.id.tv_id);

        return view;
    }


    //绑定服务
    @Override
    public void onResume() {
        super.onResume();
        Intent intent = new Intent("com.bw.aidl");
        intent.setPackage("bw.com.server");

        getContext().bindService(intent,connection, Context.BIND_AUTO_CREATE);
    }

    //解绑服务
    @Override
    public void onPause() {
        super.onPause();
        getContext().unbindService(connection);
    }
}


第四个Fragment 中  -- WebView 加载网络数据

MyFragment04.java

/**
 * A simple {@link Fragment} subclass.
 */
public class MyFragment04 extends Fragment {

    private WebView mWebView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.my_fragment04, container, false);

        mWebView = (WebView) view.findViewById(R.id.web_view_id);

        mWebView.loadUrl("http://baidu.com");

       WebSettings settings =  mWebView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);

        mWebView.setWebViewClient(new WebViewClient(){

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {

                mWebView.loadUrl("http://baidu.com");

                return super.shouldOverrideUrlLoading(view, request);
            }
        });


        return view;
    }

}






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值