Android之Socket通信、List加载更多、Spinner下拉列表

  Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信。两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据。而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求。 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信。通过建立socket连接,可为通信双方的数据传输传提供通道。socket的主要特点有数据丢失率低,使用简单且易于移植。

1.1什么是Socket
  是一种抽象层,应用程序通过它来发送和接收数据,使用Socket可以将应用程序添加到网络中,与处于同一网络中的其他应用程序进行通信。简单来说,Socket提供了程序内部与外界通信的端口并为通信双方的提供了数据传输通道。

1.2Socket的分类
  根据不同的的底层协议,Socket的实现是多样化的。本指南中只介绍TCP/IP协议族的内容,在这个协议族当中主要的Socket类型为流套接字(streamsocket)和数据报套接字(datagramsocket)。流套接字将TCP作为其端对端协议,提供了一个可信赖的字节流服务。数据报套接字使用UDP协议,提供数据打包发送服务。 下面,我们来认识一下这两种Socket类型的基本实现模型。

1.3Socket简单例子:

  服务器端Socket服务代码:

public class MyServer {

    public static void main(String[] args) throws Exception{
        ServerSocket ss = new ServerSocket(555);
        Socket s = ss.accept();
        DataInputStream dis = new DataInputStream(s.getInputStream());
        DataOutputStream dos = new DataOutputStream(s.getOutputStream());
        String str = dis.readUTF();
        System.out.print("客户端已连接");
        dos.writeUTF("Server:"+str);
        dos.flush();
        dis.close();
        s.close();
        ss.close();
    }

}

  Android客户端的代码:

public class MainActivity extends Activity {
    public static Button mybutton = null;//发送Socket请求
    public static TextView mytext = null;//显示服务器返回的值
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mybutton = (Button)findViewById(R.id.button);
        mytext = (TextView)findViewById(R.id.text);
        mybutton.setOnClickListener(new mybuttonlistener());

    }

    //按钮的点击事件
    class mybuttonlistener implements OnClickListener{

        PrintStream out = null;
        BufferedReader buf = null;
        Socket s = null;

        public void onClick(View v) {
            try {

                s = new Socket("10.20.90.3", 555);//创建一个IP地址为:10.20.90.3,端口号为:555的Socket对象

                DataOutputStream dos = new DataOutputStream(s.getOutputStream());//获得一个输出流
                DataInputStream dis = new DataInputStream(s.getInputStream());//获得一个输入流
                dos.writeUTF("河南理工大学ACM协会");//发送到服务器的请求值
                String str = dis.readUTF();//获取服务器返回的参数
                mytext.setText(str);
                dos.flush();
                dos.close();
                dis.close();
                s.close();

            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

  最简单的一个服务器<--->客户端Socket事例就实现了,客户端程序执行前,需要首先启动服务器端程序,当服务器端启动完成后,我们就可以通过Android客户端发送Socket请求了。这个事例中,我们向服务器端发送:“河南理工大学ACM协会”字段,服务器为我们返回:“Server:河南理工大学ACM协会”。代码很简单,当然关于Socket的知识绝对不仅仅包含这些,剩下的就看小伙伴们是不是感兴趣了。



  对于List的上滑加载更多,网络上有很多开源控件,本篇接下来我将带领大家一起学习一下,如何实现List的上滑加载更多。

  首先是我们的主Activity的布局文件,布局文件没有其它内容只有一个ListView控件:

<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"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:visibility="gone">
    </ListView>

</RelativeLayout>

  我们的主Activity代码:

public class MainActivity extends Activity {

    private ListView listview ;//list容器
    private List<String> data = new ArrayList<String>();//暂存数据的容器
    private ArrayAdapter<String> adapter;
    private final int number = 30;//每页的数据量
    private final int maxpage = 5;//数据的页数
    private int ItemCount;//显示的记录数
    private int nextpage;
    private boolean flag = true; //表示加载数据是否完成
    private View tipView;//页脚view

    @SuppressLint("InflateParams")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview_main);

        listview = (ListView)findViewById(R.id.listview);
        listview.setOnScrollListener(new scrollListener());//滑动事件监听
        listview.setOnItemClickListener(new onItemClickListener());//点击事件监听
        tipView = getLayoutInflater().inflate(R.layout.listview_tip, null);//获得加载更多的页脚

        /*
         * 第一次加载
         */
        data.addAll(new DataScroll().getDate(0, 30));//获得第一页需要显示的数据
        adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.listview_item, R.id.textview, data);//将数据与对应的数据显示页面配对

        /*
         * 添加页脚必须依据下面的格式
         */
        listview.addFooterView(tipView);//添加页脚(在加载数据之前)
        listview.setAdapter(adapter);//必须在此句之前加载页脚
        listview.removeFooterView(tipView);//删除页脚显示
    }

    public final class scrollListener implements OnScrollListener{

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {

        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {

            int lastItemId = listview.getLastVisiblePosition();//获得屏幕Item的最后一条记录的ID
            if((lastItemId+1)==totalItemCount){//判断是否已经拖动到页未
                if(totalItemCount > 0){//判断是否加载的数据是最后一页数据
                    int currentpage = totalItemCount%number==0 ? totalItemCount/number : totalItemCount/number+1;
                    nextpage = currentpage + 1;
                    if(nextpage<=maxpage && flag){
                        flag = false;
                        ItemCount = totalItemCount;
                        listview.addFooterView(tipView);//显示加载更多页脚
                        new Thread(new Runnable() {

                            @Override
                            public void run() {
                                //模拟网络加载数据
                                try {
                                    Thread.sleep(3000);//模拟网络加载
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                DataScroll datascroll = new DataScroll();
                                List<String> result = datascroll.getDate(nextpage, number);
                                Hand.sendMessage(Hand.obtainMessage(100, result));
                            }
                        }).start();
                    }
                }
            }

            if(0==firstVisibleItem){
                if(firstVisibleItem < 0){
                    Toast.makeText(MainActivity.this, "刷新", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    //返回到主线程执行
    Handler Hand = new Handler(){

        @SuppressWarnings("unchecked")
        @SuppressLint("HandlerLeak")
        public void handleMessage(Message msg) {
            data.addAll((List<String>) msg.obj);
            adapter.notifyDataSetChanged();//告诉ListView数据已经发生改变,要求更新ListView界面
            if(listview.getFooterViewsCount()>0){
                listview.removeFooterView(tipView);
            }
            flag = true;
        }
    };

    //List中各Item的点击事件
    class onItemClickListener implements OnItemClickListener{

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            Toast.makeText(getApplicationContext(), position+"          "+id, Toast.LENGTH_SHORT).show();
        }

    }

}

  接下来我们需要补充一下我们的Item的布局(listview_item.xml):

<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="wrap_content"
    android:background="#aa00ff"
    tools:context="${relativePackage}.${activityClass}" >

    <TextView
        android:id="@+id/textview"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:textSize="18sp"
        android:textColor="#aa0000"
        android:singleLine="true"
        />

</RelativeLayout>

  当然既然是加载更多,我们还需要一个提示用户正在加载更多的一个页脚(listview_tip.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"
    tools:context="${relativePackage}.${activityClass}" >

    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textview" />

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:textSize="18sp"
        android:textColor="#000000"
        android:singleLine="true"
        android:text="数据加载中..." />

</LinearLayout>

  当然最重要的加载数据,这里我们因为为了简单起见,就没有通过网络加载更多数据,而是通过一个模拟加载函数类实现的一个模拟加载(DataScroll.java):

/*
 * 模拟获得分页数据
 */
public class DataScroll {
    public List<String> getDate(int nextpage, int maxResult){
        int offset = 0;
        if(nextpage!=0){
            offset = (nextpage-2)*maxResult;
        }
        List<String > list = new ArrayList<String>();
        for(int i=0; i<maxResult; i++){
            list.add("List数据分批加载"+ ++offset);
        }
        return list;
    }
}

  好了,我们的上滑加载更多的实现就为大家分享完毕,关于下滑刷新,小伙伴们可以通过监听用户滑动事件,来自行研究,很简单相信大家都能实现,有疑问欢迎留言讨论。



  Spinner:Android提供的下拉列表控件,接下来我将通过5个小例子,为大家介绍一下Spinner的系统自带样式与自定义样式,当然系统自带样式相对简单,我们就从简单开始入手,为大家一一介绍Spinner的使用。

  首先是布局文件:

<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"
    tools:context="${relativePackage}.${activityClass}" >
    <LinearLayout
        android:id="@+id/linearone"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        >
        <TextView
            android:id="@+id/textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Spinner下拉列表"
            android:textSize="25dip"
            android:layout_gravity="center_horizontal"
            />

        <Spinner
            android:id="@+id/spinner1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:entries="@array/arr"
            android:spinnerMode="dropdown"
            />

        <Spinner
            android:id="@+id/spinner2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:entries="@array/brr"
            android:spinnerMode="dialog"
            />

        <Spinner
            android:id="@+id/spinner3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
        <Spinner
            android:id="@+id/spinner4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:spinnerMode="dialog"
            />
        <Spinner
            android:id="@+id/spinner5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:spinnerMode="dialog"
            />
        <Button
            android:id="@+id/buttonone"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="下一页"
            />
    </LinearLayout>
</RelativeLayout>

  前两个控件使用的是Android自带Spinner下拉列表样式,红色部分是我在res->values->strings文件中设置的值:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">下拉列表</string>
    <string name="hello_world">Hello world!</string>

    <string-array name="arr">

        <item>默认效果</item>
        <item>河南</item>
        <item>北京</item>
        <item>上海</item>

    </string-array>

    <string-array name="brr">

        <item>弹出效果</item>
        <item>河南</item>
        <item>北京</item>
        <item>上海</item>

    </string-array>

</resources>

  主Activity代码:

public class Activityone extends Activity {

    private Spinner spin1;//默认Spinner,在按钮下方显示
    private Spinner spin2;//默认Spinner,通过Dialog的形式为用户展示
    private Spinner spin3;//自定义Spinner,在按钮下方显示
    private Spinner spin4;//自定义Spinner,通过Dialog的形式为用户展示
    private Spinner spin5;//自定义Spinner,通过Dialog的形式为用户展示
    private Button buttonone;

    private String [] array = new String [] {
            "数组引用",
            "代表",
            "组长",
            "小妹"
        };

    private String [] arrayadapt = new String [] {
            "arrayadapt引用",
            "代表",
            "组长",
            "小妹"
        };

    private List<String> list = new ArrayList<String>();

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

        list.add("list引用");
        list.add("代表");
        list.add("组长");
        list.add("小妹");

        buttonone=(Button)findViewById(R.id.buttonone);
        spin1=(Spinner)findViewById(R.id.spinner1);
        spin2=(Spinner)findViewById(R.id.spinner2);
        spin3=(Spinner)findViewById(R.id.spinner3);
        spin4=(Spinner)findViewById(R.id.spinner4);
        spin5=(Spinner)findViewById(R.id.spinner5);

        ArrayAdapter<String> arrayadapter =
                new ArrayAdapter<String>(Activityone.this, android.R.layout.simple_spinner_item, arrayadapt);

        spin5.setAdapter(arrayadapter);

        BaseAdapter baseadapterone = new baseadapterone();
        spin3.setAdapter(baseadapterone);

        BaseAdapter baseadaptertwo = new baseadaptertwo();
        spin4.setAdapter(baseadaptertwo);
        //设置点击结果选择提示
        spin4.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view,
                    int position, long id) {
                Toast.makeText(Activityone.this, list.get(position), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        buttonone.setOnClickListener(new mybuttonistener());

    }

    private class baseadapterone extends BaseAdapter{

        @Override
        public int getCount() {
            return array.length;
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textview = new TextView(Activityone.this);
            textview.setText(array[position]);
            return textview;
        }

    }

    private class baseadaptertwo extends BaseAdapter{

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

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textview = new TextView(Activityone.this);
            textview.setText(list.get(position));
            return textview;
        }

    }

    class mybuttonistener implements OnClickListener{

        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Activityone.this,Activitytwo.class);
            Activityone.this.startActivity(intent);
        }
    }

}

  ok关于今天的内容介绍到此介绍,内容很简单,大家感兴趣的话可以实现一下。新手学习,高手交流。

时间: 2024-10-10 01:38:33

Android之Socket通信、List加载更多、Spinner下拉列表的相关文章

Android Demo 下拉刷新+加载更多+滑动删除

小伙伴们在逛淘宝或者是各种app上,都可以看到这样的功能,下拉刷新和加载更多以及滑动删除,刷新,指刷洗之后使之变新,比喻突破旧的而创造出新的,比如在手机上浏览新闻的时候,使用下拉刷新的功能,我们可以第一时间掌握最新消息,加载更多是什么nie,简单来说就是在网页上逛淘宝的时候,我们可以点击下一页来满足我们更多的需求,但是在手机端就不一样了,没有上下页,怎么办nie,方法总比困难多,细心的小伙伴可能会发现,在手机端中,有加载更多来满足我们的要求,其实加载更多也是分页的一种体现.小伙伴在使用手机版QQ

Android中ListView上拉加载更多及下拉刷新

做几乎每一个Android应用开发,都少不了用到一个控件,那就是ListView,用于加载多条数据,并用一定的样式展示出来.但是为了性能问题(一次性加载太多数据,比如100000条,耗费时间长,消耗资源多等)及用户体验问题(比如用户只想看最新的10条数据,结果一下子把所有的上万条数据都加载了,不方便用户选择)等原因,所以我们要把ListView的数据进行分页加载,常用的就是ListView的上拉加载更多及下拉刷新最新数据. 我们可以自己封装一个带上下拉功能的ListView,通常就是加上头部He

MVC中实现加载更多

需要实现的功能: 数据太多想初次加载部分数据,在底部加上"加载更多"按钮 点击后加载第二页数据(从数据库只取指定页数据)后接在已有数据后面(类似于android中的下拉加载更多) 每次加载时显示"正在加载--" 网上找了一些方法,类似于MvcPager分页组件,用的是v1.5.0版,但后台需要将分页后的对象列表ToPagedList,需要在MvcPager源码中加入public static PagedList<T> ToPagedList<T&g

MVC实现加载更多

MVC中实现加载更多 作者 欢醉 关注 2016.01.25 08:48 字数 945 阅读 136评论 0喜欢 2 需要实现的功能: 数据太多想初次加载部分数据,在底部加上"加载更多"按钮 点击后加载第二页数据(从数据库只取指定页数据)后接在已有数据后面(类似于android中的下拉加载更多) 每次加载时显示"正在加载--" 网上找了一些方法,类似于MvcPager分页组件,用的是v1.5.0版,但后台需要将分页后的对象列表ToPagedList,需要在MvcPa

MVC中实现 &quot;加载更多...&quot;

需要实现的功能: 数据太多想初次加载部分数据,在底部加上“加载更多”按钮 点击后加载第二页数据(从数据库只取指定页数据)后接在已有数据后面(类似于android中的下拉加载更多) 每次加载时显示“正在加载……” 网上找了一些方法,类似于MvcPager分页组件,用的是v1.5.0版,但后台需要将分页后的对象列表ToPagedList,需要在MvcPager源码中加入public static PagedList<T> ToPagedList<T>(this IList<T&g

Android MVP设计框架模板 之 漂亮ListView上拉刷新下拉加载更多

mvp的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理.MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller. 项目中大部分是面对接口编程,通过P层可以预先将所有需要的接口功能

android 安卓 listview 支持下拉刷新 上拉加载更多

[1]重写listView import java.text.SimpleDateFormat; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGrou

Android ListView 下拉刷新 点击加载更多

最近项目中用到了ListView的下拉刷新的功能,总结了一下前辈们的代码,单独抽取出来写了一个demo作为示例. 效果图 下拉刷新: 加载更多: CustomListView.java [java] view plaincopy package com.example.uitest.view; import java.util.Date; import com.example.uitest.R; import android.content.Context; import android.uti

android ListView上拉加载更多 下拉刷新功能实现(采用pull-to-refresh)

Android实现上拉加载更多功能以及下拉刷新功能, 采用了目前比较火的PullToRefresh,他是目前实现比较好的下拉刷新的类库. 目前他支持的控件有:ListView, ExpandableListView,GridView,WebView等. 下载地址:https://github.com/chrisbanes/Android-PullToRefresh 首先第一步当然是导入libriay到咱们的项目了,具体导入方式,这里不再赘述. 下面是个例子采用的是ListView,当然其余的和这