Androi:ListView+GridView实现仿微信微博朋友圈无焦点冲突

这几天还是在做那个项目 有一个部分是需要有一个类似微信朋友圈那样的功能 开始自己实现是用RecycleView嵌套RecycleView 然后已经把别的弄好了 动态图片那块还没有加上结果我不会搞也没有找到栗子 然后就换了一个思路 看到有listview+gridview的栗子就照着做了一个
先看一下现在的效果
Androi:ListView+GridView实现仿微信微博朋友圈无焦点冲突_第1张图片Androi:ListView+GridView实现仿微信微博朋友圈无焦点冲突_第2张图片
呐 这个是listview嵌套Gridview实现的 评论那些我在recycleview里面做好了之后再加 觉得 把这个嵌套弄好了真是超级开心呐;
嗯 就再回顾一下说一下思路;
1 listview适配器
2 每一个item中有一个gridview;
3 gridview也需要一个适配器
4 图片个数问题
5 图片加载和避免oom
6 我最不知道的就是gridview的adapter要放在哪里用
嗯嗯 大概这些问题都解决了的话这个demo也就ok了
这里加载用到了afinal框架 嗯嗯 我代码里面注释的很详细 因为git上的是给eclipse的 所以这个是jar包的链接afinal_0.5.1_bin.jar
可以下载复制到AS里
然后先看一下工程结构
Androi:ListView+GridView实现仿微信微博朋友圈无焦点冲突_第3张图片这里写图片描述

然后 我的顺序是先从里面往外写 最后写的MainActivity
不过 就从MainActivity里面看

package com.example.katherine_qj.listviewgridview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import com.example.katherine_qj.listviewgridviewadapter.GridViewAdapter;
import com.example.katherine_qj.listviewgridviewadapter.ListViewAdapter;
import com.example.katherine_qj.listviewwithgridbean.GridTest;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
 private List listgrid;
    private ListViewAdapter listViewAdapter;
    private ListView listView;
    private String imgs1;
    private  String imgs3;
    private  String imgs2;
    private String imgs4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listgrid = new ArrayList();
        init();
        initData();
    }
    private void  init(){
    listView = (ListView)findViewById(R.id.listview);

    }
    private void initData(){
        imgs1="http://pic60.nipic.com/file/20150211/18733170_145247158001_2.jpg#"
                +"http://mvimg1.meitudata.com/566507ca1bcc65451.jpg";
        imgs2="http://rj1.douguo.net/upload/diet/6/6/8/666f180617cab130bef1dea9fb3f7fe8.jpg#" +
               "http://img4.duitang.com/uploads/blog/201312/01/20131201120117_F5QXY.jpeg#"+
                "http://www.sh.xinhuanet.com/133071048_13905438457501n.jpg";
        imgs3="http://t2.fansimg.com/uploads2011/02/userid290276time20110205120020.jpg#" +
                "http://image81.360doc.com/DownloadImg/2015/01/2113/49316679_9.jpg#" +
                "http://image.tianjimedia.com/uploadImages/2014/133/11/EN2I6768CHU1_1000x500.jpg#"+
        "http://pic72.nipic.com/file/20150716/6659253_104414205000_2.jpg#"+
                "http://pic36.nipic.com/20131222/10558908_214221305000_2.jpg";
        imgs4 = "http://h.hiphotos.baidu.com/zhidao/pic/item/5243fbf2b21193133f9f1e3967380cd790238d5f.jpg";
        GridTest gridTest = null;
        for(int i = 0;i<=3;i++){
            gridTest = new GridTest();
            switch (i){
                case 0:gridTest.setUsername("小仙女");
                    gridTest.setHeadphoto("http://cdn.duitang.com/uploads/item/201412/12/20141212184514_BJjWy.jpeg");
                    gridTest.setContent("啊啊啊啊啊啊啊萌死了");
                    gridTest.setTime("1分钟前");
                    gridTest.setImage(imgs1);
                    break;
                case 1:
                    gridTest.setUsername("喵呜是地球吗");
                    gridTest.setHeadphoto("http://cdn.duitang.com/uploads/item/201501/19/20150119171935_ZkRsZ.thumb.224_0.jpeg");
                    gridTest.setContent("好吃的日料 超级开心的啦啦啦");
                    gridTest.setTime("3分钟前");
                    gridTest.setImage(imgs2);
                    break;
                case 2:
                    gridTest.setUsername("ill_kaaa");
                    gridTest.setHeadphoto("http://img5q.duitang.com/uploads/item/201404/03/20140403135406_XFS3M.jpeg");
                    gridTest.setContent("呐呐呐呐呐");
                    gridTest.setTime("5分钟前");
                    gridTest.setImage(imgs3);
                    break;
                case 3:
                    gridTest.setUsername("Brark");
                    gridTest.setHeadphoto("http://img3.imgtn.bdimg.com/it/u=3367770910,1075442079&fm=21&gp=0.jpg");
                    gridTest.setContent("我又在写Bug了 难过");
                    gridTest.setTime("5分钟前");
                    gridTest.setImage(imgs4);
                    break;
            }
            listgrid.add(gridTest);
        }
        listViewAdapter = new ListViewAdapter(this,listgrid);
        listView.setAdapter(listViewAdapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                Toast.makeText(MainActivity.this, "点击了第" + (position + 1) + "项", Toast.LENGTH_LONG).show();
            }
        });
    }
}

开始声明了listview的适配器 listview控件
还有四个数据源照片的链接 假数据看个样子
然后oncreat()方法里 主要有两个
init()用来找到控件
initData();很明显就是初始数据的
然后绑定适配器也是在这个里面完成

嗯 每一个item的子项都是一个类去写的
GridTest:

package com.example.katherine_qj.listviewwithgridbean;

import java.io.Serializable;

/**
 * Created by Katherine-qj on 2016/6/2.
 */
/*继承 Serializable 接口之后就可以序列化这个对象方便传输数据  很好用*/
public class GridTest implements Serializable{
    private String username;
    private String headphoto;
    private String content;
    private String time;
    private String image;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getHeadphoto() {
        return headphoto;
    }

    public void setHeadphoto(String headphoto) {
        this.headphoto = headphoto;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }
}

SysUtils类

package com.example.katherine_qj.listviewwithgridutil;

import android.app.Activity;
import android.content.Context;
import android.view.Display;
import android.view.WindowManager;

/**
 * Created by Katherine-qj on 2016/6/5.
 */
public class SysUtils {
    public  static int Dp2Px(Context context, float dp){
        final float scale = context.getResources().getDisplayMetrics().density;
       /* android context.getResources().getDisplayMetrics()这是获取手机屏幕参数,
       后面的density就是屏幕的密度,类似分辨率,但不是
       float scale = getResources().getDisplayMetrics().density;
       density值表示每英寸有多少个显示点,与分辨率是两个不同的概念。
       这个得到的不应该叫做密度,应该是密度的一个比例。不是真实的屏幕密度,而是相对于某个值的屏幕密度。
       也可以说是相对密度*/
        return (int) (dp * scale + 0.5f);
    }
    public static int getScreenWidth(Activity activity){
        WindowManager windowManager = activity.getWindowManager();
       /* WindowManager主要用来管理窗口的一些状态、属性、view增加、删除、更新、窗口顺序、消息收集和处理等。*/
        Display display = windowManager.getDefaultDisplay();
      /*  获取默认的显示对象返回值
        默认的Display对象*/
        return display.getWidth();
    }


}
    /*根据手机的分辨率从 dp 的单位 转成为 px(像素)

    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

     根据手机的分辨率从 px(像素) 的单位 转成为 dp

    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }*/

重写的GridView:MyGridView

package com.example.katherine_qj.listviewwithgrid;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;

/**
 * Created by Katherine-qj on 2016/6/2.
 */
public class MyGridView extends GridView {


    public MyGridView(Context context) {

        super(context);
    }

    public MyGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
   /* AttributeSet 是接收xml中定义的属性信息
    super后加参数的是用来调用父类中具有相同形式的构造函数
    “this通常指代当前对象,super通常指代父类*/

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }

   /*
    MeasureSpec.AT_MOST这个是由我们给出的尺寸大小和模式生成一个包含这两个信息的int变量,这里这个模式这个参数,传三个常量中的一个。
    public static int makeMeasureSpec(int size, int mode)
    这个也就是父组件,能够给出的最大的空间,当前组件的长或宽最大只能为这么大,当然也可以比这个小。
    onMeasure方法是测量view和它的内容,决定measured width和measured height的,这个方法由 measure(int, int)方法唤起,子类可以覆写onMeasure来提供更加准确和有效的测量。
    其中两个输入参数:
              widthMeasureSpec
      heightMeasureSpec
      分别是parent提出的水平和垂直的空间要求。
              这两个要求是按照View.MeasureSpec类来进行编码的。
              参见View.MeasureSpec这个类的说明:这个类包装了从parent传递下来的布局要求,传递给这个child。
              每一个MeasureSpec代表了对宽度或者高度的一个要求。
              每一个MeasureSpec有一个尺寸(size)和一个模式(mode)构成。
              MeasureSpecs这个类提供了把一个的元组包装进一个int型的方法,从而减少对象分配。当然也提供了逆向的解析方法,从int值中解出size和mode*/
}

最重要的两个适配器:::::
GridViewAdapter:

package com.example.katherine_qj.listviewgridviewadapter;

import android.app.Activity;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;

import com.example.katherine_qj.listviewgridview.R;
import com.example.katherine_qj.listviewwithgridutil.SysUtils;

import net.tsz.afinal.FinalBitmap;

import java.util.ArrayList;

/**
 * Created by Katherine-qj on 2016/6/2.
 */
public class GridViewAdapter extends BaseAdapter{

    Activity context;
    ArrayList list;
    public Bitmap bitmaps[];
    private FinalBitmap finaImageLoader;
    private int wh;
    public GridViewAdapter(Activity context,ArrayList list){
        this.context = context;
        this.list = list;
        this.wh=(SysUtils.getScreenWidth(context)-SysUtils.Dp2Px(context, 99))/3;
        this.finaImageLoader = FinalBitmap.create(context);/*获取一个FinalBitmap对象*/
        this.finaImageLoader.configLoadfailImage(R.drawable.loding);/*图片加载完成前显示的图片*/
    }

    @Override
    public int getCount() {

        return list.size();
    }

    @Override
    public Object getItem(int position) {

        return list.get(position);
    }

    @Override
    public long getItemId(int position) {

        return position;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
     Holder holder;//java内部类
        if(view==null){
            view = LayoutInflater.from(context).inflate(R.layout.item_gridview,null);
            holder = new Holder();
            holder.imageView = (ImageView)view.findViewById(R.id.imagevView);
            view.setTag(holder);
            /*首先我们要知道setTag方法是干什么的,他是给View对象的一个标签,标签可以是任何内容,
            我们这里把他设置成了一个对象,因为我们是把item_gridview.xml的元素抽象出来成为一个类ViewHolder,
            用了setTag,这个标签就是ViewHolder实例化后对象的一个属性。我们之后对于ViewHolder实例化的对象holder的操作,
            都会因为Java的引用机制而一直存活并改变convertView的内容,而不是每次都是去new一个。我们就这样达到的重用*/
        }
        else{
            holder = (Holder)view.getTag();
        }

        finaImageLoader.display(holder.imageView, list.get(position));
        AbsListView.LayoutParams param = new AbsListView.LayoutParams(wh,wh);
       /* 创建一个布局(LayoutParams)的实例 param。
        AbsListView.LayoutParams(wh,wh) 指定了该布局的宽和高;*/
        view.setLayoutParams(param);
        return view;

    }
    class Holder{
        ImageView imageView;
    }

}

ListViewAdapter:

package com.example.katherine_qj.listviewgridviewadapter;

import android.app.Activity;
import android.text.util.Linkify;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.katherine_qj.listviewgridview.R;
import com.example.katherine_qj.listviewwithgrid.MyGridView;
import com.example.katherine_qj.listviewwithgridbean.GridTest;
import com.example.katherine_qj.listviewwithgridutil.SysUtils;

import net.tsz.afinal.FinalBitmap;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Katherine-qj on 2016/6/2.
 */
public class ListViewAdapter  extends BaseAdapter{
    private LayoutInflater mInflater;
    private Activity context;
    private List list;
    private FinalBitmap finalBitmap;
    private GridViewAdapter gridViewAdapter;
    private int wh;
    public ListViewAdapter(Activity context, List list){
        super();
        this.mInflater = LayoutInflater.from(context);
        this.context = context;
        this.wh=(SysUtils.getScreenWidth(context)- SysUtils.Dp2Px(context, 99))/3;
        this.list = list;
        this.finalBitmap = FinalBitmap.create(context);
        this.finalBitmap.configLoadfailImage(R.drawable.head);
    }
    public List getlist(){
        return  list;
    }
    @Override
    public int getCount() {

        return list == null ? 0 : list.size();
    }

    @Override
    public Object getItem(int position) {

        return list == null ? null : list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return list == null ? null : position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (list.size()==0){
            return null;
        }
        final ViewHolder holder;
        if(convertView==null){
            convertView = mInflater.inflate(R.layout.item_listview,null);
            holder = new ViewHolder();
            holder.headphoto = (ImageView) convertView.findViewById(R.id.info_iv_head);//头像
            holder.disName = (TextView) convertView.findViewById(R.id.info_tv_name);//昵称
            holder.time = (TextView) convertView.findViewById(R.id.info_tv_time);//时间
            holder.content = (TextView) convertView.findViewById(R.id.info_tv_content);//发布内容
            holder.rl4=(RelativeLayout) convertView.findViewById(R.id.rl4);//图片布局
            holder.gv_images = (MyGridView) convertView.findViewById(R.id.gv_images);//图片
            convertView.setTag(holder);
        }else {
            holder = (ViewHolder)convertView.getTag();
        }
        final GridTest gridTest = list.get(position);
        String name = null,time = null,content = null,headpath = null,contentimage = null;
        if(gridTest!=null){
            name = gridTest.getUsername();
            time = gridTest.getTime();
            content = gridTest.getContent();
            headpath = gridTest.getHeadphoto();
            contentimage =gridTest.getImage();
        }
        //昵称
        if (name!=null&&!name.equals("")) {
            holder.disName.setText(name);
        }
        //是否含有图片
        if (contentimage!=null&&!contentimage.equals("")) {
            holder.rl4.setVisibility(View.VISIBLE);
            initInfoImages(holder.gv_images,contentimage);
        } else {
            holder.rl4.setVisibility(View.GONE);
        }
        //发布时间
        if (time!=null&&!time.equals("")) {
            holder.time.setText(time);
        }
        //内容
        if (content!=null&&!content.equals("")) {
            holder.content.setText(content);
            Linkify.addLinks(holder.content, Linkify.WEB_URLS);
        }
        //头像
        if (headpath!=null&&!headpath.equals("")) {
            finalBitmap.display(holder.headphoto,headpath);
        } else {
            holder.headphoto.setImageResource(R.drawable.head);
        }
        holder.headphoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Toast.makeText(context, "点击了头像", Toast.LENGTH_LONG).show();
            }
        });

        return convertView;
    }
    static class ViewHolder {
        ImageView headphoto;
        TextView disName;
        TextView time;
        TextView content;
        MyGridView gv_images;
        RelativeLayout rl4;
    }
    public void initInfoImages(MyGridView gv_images,final String imgspath){
        if(imgspath!=null&&!imgspath.equals("")){
            String[] imgs=imgspath.split("#");
            ArrayList list=new ArrayList();
            for(int i=0;iint w=0;
            switch (imgs.length) {
                case 1:
                    w=wh;
                    gv_images.setNumColumns(1);
                    break;
                case 2:
                case 4:
                    w=2*wh+SysUtils.Dp2Px(context, 2);
                    gv_images.setNumColumns(2);
                    break;
                case 3:
                case 5:
                case 6:
                    w=wh*3+SysUtils.Dp2Px(context, 2)*2;
                    gv_images.setNumColumns(3);
                    break;
            }
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(w, RelativeLayout.LayoutParams.WRAP_CONTENT);
            gv_images.setLayoutParams(lp);
            /*第一个参数为宽的设置,第二个参数为高的设置。
            如果将一个View添加到一个Layout中,最好告诉Layout用户期望的布局方式,也就是将一个认可的layoutParams传递进去
            但LayoutParams类也只是简单的描述了宽高,宽和高都可以设置成三种值:
            1,一个确定的值;
            2,FILL_PARENT,即填满(和父容器一样大小);
            3,WRAP_CONTENT,即包裹住组件就好。。*/
            gridViewAdapter=new GridViewAdapter(context, list);
            gv_images.setAdapter(gridViewAdapter);
            gv_images.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView arg0, View arg1,int arg2, long arg3) {
                    Toast.makeText(context, "点击了第"+(arg2+1)+"张图片", Toast.LENGTH_LONG).show();
                }
            });
        }

    }

}

上面就是所有的类了 代码里面的注释挺详细的

还有三个layout;
分别是listview的item
gridview的item
还有activity_main
代码贴上来吧
activity_main:


<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@android:color/transparent"
        android:divider="#70CDCDCD"
        android:dividerHeight="0.5dp"
        android:fadingEdge="none"
        android:fastScrollEnabled="true"
        android:listSelector="@drawable/list_item_selector"
        android:scrollbars="none" >
ListView>
    
    
    
    
    
    

RelativeLayout>

item_gridview:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <ImageView
        android:id="@+id/imagevView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="centerCrop"/>
LinearLayout>
   

item_listview:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl_info"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:descendantFocusability="blocksDescendants">
    
    
    <ImageView
        android:id="@+id/info_iv_head"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/head"/>
    <RelativeLayout
        android:id="@+id/rl1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@+id/info_iv_head">
        <TextView
            android:id="@+id/info_tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:text="小仙女"
            android:textColor="#444444"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/info_tv_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="一分钟前"
            android:textColor="#BEBBB4"
            android:textSize="12sp" />

    RelativeLayout>
    <RelativeLayout
        android:id="@+id/rl3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/rl1"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        android:paddingBottom="5dp"
        android:paddingRight="5dp"
        android:paddingTop="5dp" >

        <TextView
            android:id="@+id/info_tv_content"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="50dp"
            android:text="李睿豪是傻逼哦,李睿豪是傻逼哦,李睿豪是傻逼哦,李睿豪是傻逼哦,李睿豪是傻逼哦,李睿豪是傻逼哦"
            android:textColor="#615150"
            android:textSize="14sp" />
    RelativeLayout>
    <RelativeLayout
        android:id="@+id/rl4"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
       android:layout_below="@+id/rl3"
        android:paddingRight="25dp"
        android:visibility="gone" >
     

        <com.example.katherine_qj.listviewwithgrid.MyGridView
            android:id="@+id/gv_images"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:horizontalSpacing="2dp"
            android:listSelector="@null"
            android:numColumns="3"
            android:stretchMode="columnWidth"
            android:verticalSpacing="2dp" >
        com.example.katherine_qj.listviewwithgrid.MyGridView>
    RelativeLayout>

RelativeLayout>

还有一个就是一个selector
list_item_selector:


<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@color/item_back_press" android:state_enabled="true" android:state_focused="true" android:state_pressed="false"/>
    <item android:drawable="@color/item_back_press" android:state_enabled="true" android:state_pressed="true"/>
    <item android:drawable="@color/item_back_press" android:state_checked="true" android:state_enabled="true"/>

selector>

嗯 所有的有关于实现的都在上面了

其实主要难点就在嵌套的时候gridview的适配器怎么搞 在那里加 数据源怎么传进去。

这里的数据源是网络图片 所以我们用了一个现成的框架 代码里面有注释 大概oom’之类的问题可以不用考虑
嗯 这里是把gridview当成子项中的一个部分 所以肯定是要写在listviewadapter的getview方法里给它绑定监听器 大概就这样
以上over!
源码在这里 嗯 上传失败了。。。

你可能感兴趣的:(安卓)