开发者

Problem using tabs that contains listviews (Android)

I have tried to create one tabhost with two tabs. Each tab contains one listview. Here is the code for the java file

package com.Bussruter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import android.app.AlertDialog;
import android.app.TabActivity;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TabHost.TabContentFactory;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.TabHost.OnTabChangeListener;

public class Bussruter extends TabActivity implements OnTabChangeListener {
    /** Alle */
    private static final String LIST1_TAB_TAG = "List1";
    /** Nedlastet */
    private static final String LIST2_TAB_TAG = "List2";

    private StorageHandler sh;
    private Resources res;// Resource object to get Drawables
    private ListView lvNedlastet;
    private ListView lvAlle;
    private TabHost th;

    /*private int[] created = new int[]{
            0,
            20100108,
            0
    };*/
    /** Called when the activity is first created. */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);


      //Checking which pdfs are already downloaded.
      sh = new StorageHandler();
      this.checkAvaliablePdfs();
      th = getTabHost();
      res = getResources();
      th.setOnTabChangedListener(this);
      lvAlle = (ListView) findViewById(R.id.list1);
      lvNedlastet = (ListView) findViewById(R.id.list2);

      lvAlle.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, new String[]{"1"}));//sh.getListNameAlle()));
      lvNedlastet.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_2, new String[]{"1"}));//sh.getListNameNedlastet()));


      OnItemClickListener itemCLAlle = this.createClickListenerAlle();
      OnItemClickListener itemCLNedlastet = this.createClickListenerNedlastet();

      lvAlle.setOnItemClickListener(itemCLAlle);
      lvNedlastet.setOnItemClickListener(itemCLNedlastet);

      OnItemLongClickListener itemLCL = this.createLongClickListener();
      lvAlle.setOnItemLongClickListener(itemLCL);
      lvAlle.setLongClickable(true);
      lvNedlastet.setOnItemLongClickListener(itemLCL);
      lvNedlastet.setLongClickable(true);

      th.addTab(th.newTabSpec(LIST2_TAB_TAG)
                .setIndicator(LIST2_TAB_TAG,
                        res.getDrawable(R.drawable.ic_tab_nedlastet))
                .setContent(new TabContentFactory() {
                    public View createTabContent(String arg0) {
                        return lvNedlastet;
                    }
                }));
      th.addTab(th.newTabSpec(LIST1_TAB_TAG)
                .setIndicator(LIST1_TAB_TAG,
                        res.getDrawable(R.drawable.ic_tab_alle))
                .setContent(new TabContentFactory() {
                    public View createTabContent(String arg0) {
                        return lvAlle;
                    }
                }));

      th.setCurrentTabByTag(LIST1_TAB_TAG);
    }

    private OnItemLongClickListener createLongClickListener() {
        return 
        new OnItemLongClickListener() {
            public boolean onItemLongClick(AdapterView<?> parent, final View view,
                       final int position, long id) {
                if(isAvailable(position)){
                    try{
                        new AlertDialog.Builder(parent.getContext())
                        .setMessage("Vil du slette bussruten?")
                        .setCancelable(false)
                        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {

                                deleteFile(view, position);
                                sh.availability[position] = false;
                            }
                        })
                        .setNegativeButton("No", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                            }
                        })
                        .show();
                    }catch(Exception e){
                        toastText("ERROR: "+e.getMessage(), Toast.LENGTH_LONG);
                    }
                    return true;
                }else return false;
            }
        };
    }

    private OnItemClickListener createClickListenerAlle(){
        return 
            new OnItemClickListener() {
               public void onItemClick(AdapterView<?> parent, View view,
                       int position, long id){  

                   boolean temp = sh.availability[position];
                   if(temp == true){
                       if(Environment.getExternalStorageState().equals(
                               Environment.MEDIA_MOUNTED)){
                 开发者_C百科          File file = new File(StorageHandler.sdcardUrl+ StorageHandler.uniqueBussFilename[position]);

                           if (file.exists()) {//open the file
                               Uri path = Uri.fromFile(file);
                               Intent intent = new Intent(Intent.ACTION_VIEW);
                               intent.setDataAndType(path, "application/pdf");
                               intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                               try {
                                   startActivity(intent);
                               } 
                               catch (ActivityNotFoundException e) {
                                   toastText("No Application Available for viewing PDF", Toast.LENGTH_LONG);
                               }
                           }else{
                               toastText("The file "+file.getAbsolutePath()+" was not found.", Toast.LENGTH_LONG);
                           }
                       }else{
                           toastText("sdkort er ikke tilgjengelig.", Toast.LENGTH_LONG);
                       }
                   }else{//Have to download the file.
                       connect();   
                       try { 
                            String absUrl = StorageHandler.webUrl[position];
                            InputStream inputStream = OpenHttpConnection(absUrl);
                            File tempFile = new File(StorageHandler.sdcardUrl+StorageHandler.uniqueBussFilename[position]);
                            File tempFile2 = new File(StorageHandler.sdcardUrl);
                            if(!tempFile.exists()){
                                tempFile2.mkdirs();
                                tempFile.createNewFile();
                            }
                            OutputStream output = new FileOutputStream(tempFile);
                            int bytesRead;
                            byte[] buffer = new byte[8 * 1024];
                            while((bytesRead = inputStream.read(buffer)) != -1){
                                output.write(buffer,0,bytesRead);
                            }


                            output.close();
                            inputStream.close();

                            toastText("Bussruten er lastet ned.", Toast.LENGTH_LONG);
                            sh.availability[position] = true;
                        } catch (IOException e) {
                            toastText("ERROR:Kan ikke laste ned bussruten.\nStacktrace:\n"+e.getMessage(), Toast.LENGTH_LONG);
                        }
                   }
               }
            };
    }

    private OnItemClickListener createClickListenerNedlastet(){
        return 
        new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                   int position, long id){  

               boolean temp = sh.availability[position];
               if(temp == true){
                   if(Environment.getExternalStorageState().equals(
                           Environment.MEDIA_MOUNTED)){
                       File file = new File(StorageHandler.sdcardUrl+ StorageHandler.uniqueBussFilename[position]);

                       if (file.exists()) {//open the file
                           Uri path = Uri.fromFile(file);
                           Intent intent = new Intent(Intent.ACTION_VIEW);
                           intent.setDataAndType(path, "application/pdf");
                           intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                           try {
                               startActivity(intent);
                           } 
                           catch (ActivityNotFoundException e) {
                               toastText("No Application Available for viewing PDF", Toast.LENGTH_LONG);
                           }
                       }else{
                           toastText("The file "+file.getAbsolutePath()+" was not found.", Toast.LENGTH_LONG);
                       }
                   }else{
                       toastText("sdkort er ikke tilgjengelig.", Toast.LENGTH_LONG);
                   }
               }
            };
        };
}
    private boolean isConnected(){
        if(sh.isEmulator){
            return true;
        }else{
            ConnectivityManager connMan = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
            if (connMan.getActiveNetworkInfo().isConnected()){//getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) {
                return true;
            }else{
                return false;
            }
        }
    }
    private void toastText(String t, int l){
        final String text = t;
        final int length = l;
        Toast.makeText(getApplicationContext(), text, length).show();               

    }
    private void connect(){
        if(isConnected()){
            sh.isConnected = true;
            toastText("Kobler til...", Toast.LENGTH_SHORT);
        }else{
            sh.isConnected = false;
            toastText("Bussruten har ikke blitt lastet ned.\n" +
                    "Vennligst koble til internet for å laste ned ruten", Toast.LENGTH_LONG);   
        }
    }
    private InputStream OpenHttpConnection(String urlString) 
    throws IOException
    {
        InputStream in = null;
        int response = -1;

        URL url = new URL(urlString);
        URLConnection conn = url.openConnection();
        if (!(conn instanceof HttpURLConnection))                     
            throw new IOException("Not an HTTP connection");

        try{
            HttpURLConnection httpConn = (HttpURLConnection) conn;
            httpConn.setAllowUserInteraction(false);
            httpConn.setInstanceFollowRedirects(true);
            httpConn.setRequestMethod("GET");
            httpConn.connect(); 

            response = httpConn.getResponseCode();                 
            if (response == HttpURLConnection.HTTP_OK) {
                in = httpConn.getInputStream();                                 
            }                     
        }
        catch (Exception ex)
        {
            throw new IOException("Error connecting");            
        }
        return in;     
    }
    /*
    private String urlWithSpaces2Percentage20(String url){
        String output = "";
        for(int i = 0;i<url.length();i++){
            char c = url.charAt(i);
            if(c == ' '){
                output = output + "%20";
            }else{
                output = output + c;
            }
        }
        return output;
    }
    private int getCreatedDateFromFullName(String name){
        return 0;
    }*/
    private boolean isAvailable(int position){
        File f = new File(StorageHandler.sdcardUrl + StorageHandler.uniqueBussFilename[position]);
        if(f.exists()){
            return true;
        }
        return false;
    }
    private void checkAvaliablePdfs(){
        for(int i = 0;i<StorageHandler.uniqueBussFilename.length;i++){
            File f = new File(StorageHandler.sdcardUrl + StorageHandler.uniqueBussFilename[i]);
            if(f.exists()){
                sh.availability[i] = true;
            }
        }
    }
    private void deleteFile(View view, int index){
        try{
            File f =  new File(StorageHandler.sdcardUrl + StorageHandler.uniqueBussFilename[index]);
            f.delete();
        }catch(Exception e){
            toastText("ERROR: "+e.getMessage(), Toast.LENGTH_LONG);
        }
    }
    /*
    private void setTextColor(View view, int id){
        if(availability[id]){
            view.setPressed(true);
        }
    }*/

    /**
     * Implement logic here when a tab is selected
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void onTabChanged(String tabName) {
        if(tabName.equals(LIST2_TAB_TAG)) {
            lvNedlastet.setAdapter(new ArrayAdapter(this, 
                    android.R.layout.simple_list_item_2, 
                    sh.getListNameNedlastet()));
        }
        else if(tabName.equals(LIST1_TAB_TAG)) {
            //do something
        }
    }
}

And here is the code for the main.xml

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout android:orientation="vertical"
        android:layout_width="fill_parent" android:layout_height="fill_parent">
        <TabWidget android:id="@android:id/tabs"
            android:layout_width="fill_parent" android:layout_height="wrap_content" />
        <FrameLayout android:id="@android:id/tabcontent"
            android:layout_width="fill_parent" android:layout_height="fill_parent">
            <ListView android:id="@+id/list1" android:layout_width="fill_parent"
                android:layout_height="wrap_content" android:layout_weight="1">
            </ListView>
            <ListView android:id="@+id/list2" android:layout_width="fill_parent"
                android:layout_height="wrap_content" android:layout_weight="1">
            </ListView>
        </FrameLayout>
    </LinearLayout>
</TabHost>

And here is the Error message from the DDMS

01-19 21:40:13.198: ERROR/AndroidRuntime(16123): Uncaught handler: thread main exiting due to uncaught exception
01-19 21:40:13.838: ERROR/AndroidRuntime(16123): java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:347)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.ArrayAdapter.getView(ArrayAdapter.java:323)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.AbsListView.obtainView(AbsListView.java:1274)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1147)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.ListView.onMeasure(ListView.java:1060)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.View.measure(View.java:7964)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.View.measure(View.java:7964)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:888)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:350)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:278)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.View.measure(View.java:7964)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.View.measure(View.java:7964)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.View.measure(View.java:7964)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:464)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:278)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.View.measure(View.java:7964)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.View.measure(View.java:7964)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.ViewRoot.performTraversals(ViewRoot.java:763)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.os.Looper.loop(Looper.java:123)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.app.ActivityThread.main(ActivityThread.java:4363)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at java.lang.reflect.Method.invokeNative(Native Method)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at java.lang.reflect.Method.invoke(Method.java:521)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at dalvik.system.NativeStart.main(Native Method)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123): Caused by: java.lang.ClassCastException: android.widget.TwoLineListItem
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:340)
01-19 21:40:13.838: ERROR/AndroidRuntime(16123):     ... 35 more

In advance. THANKS! :)


It's a pretty straightforward error message. From the docs:

A ListAdapter that manages a ListView backed by an array of arbitrary objects. By default this class expects that the provided resource id references a single TextView. If you want to use a more complex layout, use the constructors that also takes a field id. That field id should reference a TextView in the larger layout resource.

Basically, in your onTabChanged method, when you're constructing the ArrayAdapter, instead of android.R.layout.simple_list_item_2, it's expecting the id of a TextView, not of a layout. You need to use a different constructor that takes a resource AND a TextView id, so in this case, you should be able to use:

lvNedlastet.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_2,
    android.R.id.text1, sh.getListNameNedlastet())); 

If it's more complicated than a single TextView, you should probably look into creating your own custom list adapter.


there are many confusions for me here, (i never build the ListView this way... ) but i thing that the error you get is because you constructs the ArrayAdapter with a layout resource (2nd parameter) when ArrayAdapter expects that the second parameter be a TextView resource. Or if the second parameter is a layout, that layout must hold a TextView, and i don´t sure if android.R.layout.simple_list_item_1 holds a TextView, so, try this instead;

lvAlle.setAdapter(new ArrayAdapter(this, android.R.layout.android.R.id.text1, new String[]{"1"}));//sh.getListNameAlle()));

maybe i dont understand your question, but hope this help.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜