处理ListView中Item单击

小组成员: OOOO   最终完成日期:15年00月00日

一、简介

简要介绍本模块所要完成的功能。

二、基础知识

简要介绍本模块所需掌握的基础知识

  • Intent传递数据:

           从天气预报的主界面(即天气情况显示界面)到城市列表界面是通过Intent来启动一个新的Activity的,现在,我们在点击城市列表的某个城市的时候,我们需要将所点击的城市信息作为参数传回主界面的Activity并进行相应的查询显示等处理。 这时,发起方(主界面)要调用startActivityForResult(Intent intent, int requestCode)
           同时发起方要实现onActivityResult(int requestCode, int resultCode, Intent intent)来获取返回结果。        这样MainActivity才可以根据获得的cityCode更新城市天气。那么同时在城市列表的Activity中,则要在finish()之前,将数据放入intent中,并调用setResult(int resultCode, Intent intent)方法,设置返回结果。

  • ListView中Item单击和长按事件:

      单击事件注册监听事件示例:
      listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
          @Override
          public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
              Toast.makeText(listview.this,"你单击的是第"+(position+1)+"条数据",Toast.LENGTH_SHORT).show();
          }
      });
      长按事件注册监听事件示例:
      listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
          @Override
          public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
              Toast.makeText(listview.this,"你长按的是第"+(position+1)+"条数据",Toast.LENGTH_SHORT).show();
              return false;
          }
      });
      我们可以通过以上方法注册不同的监听事件,响应不同的操作,比如我们可以在单击事件里面跳转到其他页面,也可以在长按事件里面弹出一个小窗口。操作是比较灵活的。
    
      下面介绍一下单击和长按事件个参数的意义:
      parent相当于listview适配器的一个指针,通俗一点讲就是可以通过它来获得listview里装着的一切东西。
      View view, view是你点击item的view的句柄,就是你可以用这个view,来获得item里的控件的id后操作控件。
      int position, position是item在适配器里的位置。
      long id,id是item在listview 里的第几行的位置,大部分时候position和id的值是一样的。
    
  • 自定义ListItem单击事件

      ListItem点击事件可以分为,单击ListItem事件和长按ListItem事件。但是这两个功能并非全能的,例如在手机通讯录中,某一时间可能打电话给甲,另一时间则是发短信,或者长按删除联系人甲。这是单击事件和长按事件就无法满足实际需求。
      不过ListView提供了SimpleAdapter用来绑定用户自定义控件和数据。通过调用getView()方法,为List中每个Item返回一个自定义View,此时可以对View中相关控件添加监听函数。
      具体实现:
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          // TODO Auto-generated method stub
          View view;
          if(convertView == null){
              view = mInflater.inflate(R.layout.layout_list_click2, null);
          } else {
              view = convertView;
          }            
          ...
          //从当前view中选择需要添加监听函数的控件
          View icon = view.findViewById(R.id.imageView1);
          //为自定义ListViewItem中控件添加点击监听函数
          icon.setOnClickListener(new View.OnClickListener() {
          public void onClick(View v) {
              // TODO Auto-generated method stub
              //添加事件处理流程
              }
          });
          return view;
      }
    

三、主要思路及步骤

3.1 主要思路

当响应单击事件时:
    首先设置监听函数,即调用OnItemClickListener()函数;
    接着,在处理函数内部,设置处理流程,OnItemClick().
响应长按事件:
    首先触发的是onItemLongClick函数,执行onItemLongClick操作;
    其次,然后根据onItemLongClick的返回值判断是不是执行OnCreateContextMenuListener函数;
    如果onItemLongClick返回false,则会继续执行OnCreateContextMenuListener函数。
响应自定义控件事件:
    首先调用getView()函数,在其中绑定控件;
    其次设置该空间监听函数,并处理事件。

3.2 实践步骤

        在上一节中,已经通过ListView展示出城市列表,如下图所示:

       这些城市列表是通过SelectCity活动中的ListView来展示的,在SelectCity类中,我们可以定义每个ListView中的Item被单击时的行为。例如本程序在单击某个城市后,返回主页面进行显示天气。 代码如下:


public class SelectCity extends Activity implements View.OnClickListener{

    private ImageView mBackBtn;
   // private String[] data;
    private List<String> data=new ArrayList<String>();
    private ListView mlistView;

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

        mlistView=(ListView)findViewById(R.id.list_view);

        MyApplication application= (MyApplication) this.getApplication(); //获取MyApplication,可以通过Activity的getApplicaion()方法
        //MyApplication application=(MyApplication) getApplicationContext(); //获取MyApplication,也可以通过Context的getApplicationContext()方法
        data=application.getMCityList();  //获取全局变量

        ArrayAdapter<String> adapter=new ArrayAdapter<String>(
                this,android.R.layout.simple_list_item_1,data);
        mlistView.setAdapter(adapter);
        //setContentView(mlistView);

        mBackBtn = (ImageView)findViewById(R.id.title_back);
        mBackBtn.setOnClickListener(this);

        //单击listView中的view
        mlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Log.d("selectcityname",data.get(i));
                Toast.makeText(SelectCity.this,"你单击了:"+i,Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(SelectCity.this,tianqiActivity.class);//这里tianqiActivity.class是主活动。在主活动中再通过所选择的城市查询天气
                intent.putExtra("cityName",data.get(i));
                //startActivity(intent);

                setResult(RESULT_OK,intent);
                finish(); 
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_select_city, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void onClick(View view){
        switch (view.getId()){
            case R.id.title_back:
                finish();
                break;


            default:
                break;
        }
    }
}

       我们在SelectCity活动中通过mlistView.setOnItemClickListener()方法来定以定义单击item后的活动,我们先通过Toast.makeText弹出提示框,提示我们选择了第几个城市,然后再通过Intent把选择的城市传到主活动(tianqiActivity.class)中。

       下图是单击item后的效果。这里我们选择“海淀”。

因为item是从0开始计数的,所以海淀序号为1。

        把选择的城市通过Intent的方法setResult(RESULT_OK,intent)发送到主活动以后,主活动通过onActivityResult()方法接受Intent。         因为之前查询某个城市的天气是通过城市编码,这里改成了城市名称,所以我们在查询城市天气的方法也稍作修改,具体如下:

protected void onActivityResult(int requestCode,int resultCode,Intent intent){
        if(requestCode==1 && resultCode==RESULT_OK){
            String cityname=intent.getStringExtra("cityName");
            Log.d("cityname", cityname);
            queryWeatherCode(cityname, 2);//这里应该按照选择的城市进行查询
           // queryWeatherCode("101010100",1);
        }
    }

    /**
    * 根据城市查询所对应的天气信息
    *
    */
    private void queryWeatherCode(String cityCode, int arg){
    //第二个参数arg有两个值,1和2,arg为1时cityCode表示城市编码,arg为2时cityCode表示城市名称。
        Log.d("queryWeatherCode",cityCode);
        final int flag=arg;
        final String address1 = "http://wthrcdn.etouch.cn/WeatherApi?citykey="+cityCode;
        final String address2 = "http://wthrcdn.etouch.cn/WeatherApi?city="+cityCode;

        Log.d("myWeather", address1);
        Log.d("myWeather", address2);

        new Thread(new Runnable(){
            @Override
            public void run() {
                try{
                   // URL url=new URL("http://wthrcdn.etouch.cn/WeatherApi?citykey="+cityCode);
                    /*URLConnection urlConnection=url.openConnection();
                    HttpURLConnection httpUrlConnection=(HttpURLConnection) urlConnection;
                    BufferedReader reader=new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));*/

                    HttpClient httpClient=new DefaultHttpClient();
                    HttpGet httpget=null;

                    if(flag==1){
                        httpget=new HttpGet(address1);
                    }
                    else if(flag==2){
                        httpget=new HttpGet(address2);
                    }
                    HttpResponse httpResponse = httpClient.execute(httpget);
                    if(httpResponse.getStatusLine().getStatusCode()==200) {
                        HttpEntity entity = httpResponse.getEntity();
                        InputStream responseStream = entity.getContent();
                        responseStream = new GZIPInputStream(responseStream);
                        BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream));

                        StringBuilder response = new StringBuilder();
                        String str;
                        while ((str = reader.readLine()) != null) {
                            response.append(str);
                        }
                        String responseStr = response.toString();
                        Log.d("myWeather1", responseStr);
                        TodayWeather todayWeather = parseXML(responseStr);

                        if (todayWeather != null) {
                            Log.d("myapp2",todayWeather.toString());
                            //发送消息,由主线程更新UI
                            Message msg = new Message();
                            msg.what = UPDATE_TODAY_WEATHER;
                            msg.obj = todayWeather;
                            mHandler.sendMessage(msg);
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();
    }

以上就是在单击Item后,程序的整个过程。

四、常见问题及注意事项

详细描述本部分的常遇到的问题以及开发过程中的注意事项

results matching ""

    No results matching ""