0

嗨,我是 android 开发的初学者,我正在做一个学校作业,我们将在其中制作 n 应用程序,该应用程序有一个用于搜索的文本字段,它将使用该字符串来查询烂番茄的开放 API。这将显示为列表并稍后进行操作。

我现在已经走到了最后。搜索、添加和获取类似电影都可以正常工作(还有 gui),但我无法从 db/list 中删除(如果需要,我将电影保存到其中),我不知道为什么。我认为我以正确的方式使用意图,但显然不是。

完整代码:

// MainActivity.java

     package geemoney.movieeservice;

import android.os.Bundle;
import android.app.TabActivity;
import android.content.Intent;
import android.view.Menu;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;

public class MainActivity extends TabActivity {

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

        /** TabHost (main container of tab view, the top rectangle) will have Tabs */
        TabHost tabHost = (TabHost)findViewById(android.R.id.tabhost);

        /** TabSpec used to create a new tab.
        * By using TabSpec only we can able to setContent to the tab.
        * By using TabSpec setIndicator() we can set name to tab. */

        /** tid1 is firstTabSpec Id. Its used to access outside. */
        TabSpec firstTabSpec = tabHost.newTabSpec("tid1");
        TabSpec secondTabSpec = tabHost.newTabSpec("tid2");

        /** TabSpec setIndicator() is used to set name for the tab. */
        /** TabSpec setContent() is used to set content for a particular tab. */
        firstTabSpec.setIndicator("Search").setContent(new Intent(this,SearchTab.class));
        secondTabSpec.setIndicator("My List").setContent(new Intent(this,MylistTab.class));

        /** Add tabSpec to the TabHost to display. Adding the newly created tabs to its container */
        tabHost.addTab(firstTabSpec);
        tabHost.addTab(secondTabSpec);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

// 两个新的类/选项卡之一,这个调用了 SearchTab

package geemoney.movieeservice;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import database.DBAdapter;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;


public class SearchTab extends Activity {
    ArrayList<String> list = new ArrayList<String>();
    List<Map<String, String>> data;
    SimpleAdapter aa;
    Map<String, String> item;
    String apiKey = "chhgsd429xb9fs6wq3kqzhmk";
    String current = "";
    MylistTab mt = new MylistTab();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search);

        /* First Tab Content */
        Button addButton = (Button) findViewById(R.id.add);
        Button similarButton = (Button) findViewById(R.id.similar);
        Button searchButton = (Button) findViewById(R.id.search);
        addButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (current != ""){
                    add();
                }else {
                    Toast.makeText(getApplicationContext(), "You need to select a list item",Toast.LENGTH_LONG).show();
                }
            }
        });
        similarButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (current != ""){
                    similar();
                }else {
                    Toast.makeText(getApplicationContext(), "You need to select a list item",Toast.LENGTH_LONG).show();
                }
            }
        });
        searchButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                EditText userInput = (EditText) findViewById(R.id.searchstring);
                if ((!(userInput.getText().toString().isEmpty()))) {
                    search();
                }else {
                    Toast.makeText(getApplicationContext(), "You need insert a search string",Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    protected void add() {
        DBAdapter db = new DBAdapter(this);
        String id = current.substring(current.indexOf("id=") + 3, current.indexOf(" ", current.indexOf("id=") + 3) - 1);
        String title = current.substring(current.indexOf("title=") + 6, current.indexOf("}", current.indexOf("title=")));
        String year = current.substring(current.indexOf("year=") + 5, current.indexOf(" ", current.indexOf("year=") + 5) - 1);
        db.open();
        db.insertTitle(id, title, year);
        db.close();
        Toast.makeText(getApplicationContext(), "Added to DB", Toast.LENGTH_LONG).show();
    }

    protected void search() {
        data = new ArrayList<Map<String, String>>();
        list = new ArrayList<String>();
        EditText searchstring = (EditText) findViewById(R.id.searchstring);
        String query = searchstring.getText().toString().replace(' ', '+');
        String text = searchquery(query);

        try {
            JSONObject res = new JSONObject(text);

            JSONArray jsonArray = res.getJSONArray("movies");

            for (int i = 0; i < jsonArray.length(); i++) {

                JSONObject jsonObject = jsonArray.getJSONObject(i);
                item = new HashMap<String, String>(2);
                item.put("id",jsonObject.getString("id"));
                item.put("title",jsonObject.getString("title"));
                item.put("year", jsonObject.getString("year"));
                data.add(item);

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

        aa = new SimpleAdapter(SearchTab.this, data,
                R.layout.mylistview,
                new String[] {"title", "year"},
                new int[] {R.id.text1,
                R.id.text2});
        ListView lv = (ListView) findViewById(R.id.listView1);
        lv.setAdapter(aa);
        lv.setDividerHeight(5); 

        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {

                Map<String, String> s = data.get((int) id);
                current = s.toString();
                // HERE INTENT
                Intent i = new Intent(SearchTab.this, MylistTab.class);

            }});
    }

    private String searchquery(String searchString) {
        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet("http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey="+apiKey + "&q="+searchString + "&page_limit=10");
        try {
            HttpResponse response = client.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
            } else {
                Log.e("QueryDB", "Failed to download file");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder.toString();
    }

    protected void similar() {
        data = new ArrayList<Map<String, String>>();
        list = new ArrayList<String>();
        //id=12897, year=1999, title=The Matrix
        String id = current.substring(current.indexOf("id=") + 3, current.indexOf(" ", current.indexOf("id=") + 3) - 1);
        String text;

        text = similarquery(id);
        try {
            JSONObject res = new JSONObject(text);

            JSONArray jsonArray = res.getJSONArray("movies");

            for (int i = 0; i < jsonArray.length(); i++) {

                JSONObject jsonObject = jsonArray.getJSONObject(i);
                item = new HashMap<String, String>(2);
                item.put("id",jsonObject.getString("id"));
                item.put("title",jsonObject.getString("title"));
                item.put("year", jsonObject.getString("year"));
                data.add(item);

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

        aa = new SimpleAdapter(SearchTab.this, data,
                R.layout.mylistview,
                new String[] {"title", "year"},
                new int[] {R.id.text1,
                R.id.text2});
        ListView lv = (ListView) findViewById(R.id.listView1);
        lv.setAdapter(aa);
        lv.setDividerHeight(5); 

        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {

                Map<String, String> s = data.get((int) id);
                current = s.toString();
                // HERE INTENT
            }});
    }

    private String similarquery(String id) {
        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet("http://api.rottentomatoes.com/api/public/v1.0/movies/"+id+"/similar.json?apikey="+apiKey +"&limit=5");

        try {
            HttpResponse response = client.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
            } else {
                Log.e("QueryDB", "Failed to download file");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder.toString();
    }
}

// mylisttab.java

        package geemoney.movieeservice;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import database.DBAdapter;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class MylistTab extends Activity {
    ArrayList<String> list = new ArrayList<String>();
    List<Map<String, String>> data;
    SimpleAdapter aa;
    DBAdapter db = new DBAdapter(this);
    String current = "";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mylist);

        /* First Tab Content */
        Button deleteButton = (Button) findViewById(R.id.remove);
        deleteButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (current != "") {
                    delete();   
                }else {
                    Toast.makeText(getApplicationContext(), "You need to select a list item",Toast.LENGTH_LONG).show();
                }
            }
        });
        populate();
    }

    public void delete() {
        if (current != null) 
        {
            db.open();
            db.deleteTitle(current);
            Toast.makeText(getApplicationContext(), "CURRENT IS:" +current, Toast.LENGTH_SHORT).show();
            Toast.makeText(getApplicationContext(), "Title deleted", Toast.LENGTH_SHORT).show();
            db.close(); 
        }
    }

    private void populate() {
        db.open();
        Cursor fetchInfo = db.fetchAllRecords();
        startManagingCursor(fetchInfo);

        // Create an array to specify the fields we want to display in the list (TITLE,YEAR)
        String[] from = new String[]{DBAdapter.KEY_TITLE, DBAdapter.KEY_YEAR};

        // an array of the views that we want to bind those fields to (in this case text1,text2,text3)
        int[] to = new int[]{R.id.text1, R.id.text2};

        // Now create a simple cursor adapter and set it to display
        ListView lv = (ListView) findViewById(R.id.listView1);
        SimpleCursorAdapter aa = new SimpleCursorAdapter(MylistTab.this, R.layout.mylistview, fetchInfo, from, to);
        lv.setAdapter(aa);
        lv.setDividerHeight(5);
        db.close();
    }
}

// 活动.main.xml

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

<TabHost 
android:layout_width="fill_parent"
android:layout_height="fill_parent" 
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost">

<LinearLayout 
android:id="@+id/LinearLayout01"
android:orientation="vertical" 
android:layout_height="fill_parent"
android:layout_width="fill_parent">

<TabWidget 
android:id="@android:id/tabs"
android:layout_height="wrap_content" 
android:layout_width="fill_parent">
</TabWidget>

<FrameLayout 
android:id="@android:id/tabcontent"
android:layout_height="fill_parent" 
android:layout_width="fill_parent">
</FrameLayout>
</LinearLayout>

</TabHost>

// mylist.xml

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/remove"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginBottom="15dp"
        android:layout_marginTop="15dp"
        android:text="@string/remove" />

    <ListView
        android:id="@+id/listView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/remove" >

    </ListView>

</RelativeLayout>

// mylistview.xml

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

    <TextView
        android:id="@+id/text1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="16dp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/text2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="12dp"
        android:textStyle="italic" />

</LinearLayout>

// 搜索.xml

    <?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <EditText
        android:id="@+id/searchstring"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        android:ems="10"
        android:gravity="center_vertical"
        android:inputType="textAutoComplete" >
    </EditText>

    <Button
        android:id="@+id/search"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/searchstring"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="14dp"
        android:text="@string/search" />

    <ListView
        android:id="@+id/listView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/search"
        android:layout_marginTop="20dp"
        android:clickable="true"
        android:focusable="true"
        android:focusableInTouchMode="true" >
    </ListView>

    <Button
        android:id="@+id/add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/listView1"
        android:layout_alignParentLeft="true"
        android:text="@string/addTitle" />

    <Button
        android:id="@+id/similar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/listView1"
        android:layout_marginLeft="16dp"
        android:layout_toRightOf="@+id/search"
        android:text="@string/similar" />

</RelativeLayout>

Now, why cant I place an intent at searchtab in the method similar() (or earlier) where I get the ID and positive of it since im using it to populate mylist like: There I get the ID by this code:

ListView lv = (ListView) findViewById(R.id.listView1);
lv.setOnItemClickListener(new OnItemClickListener() 
{
public void onItemClick(AdapterView<?> parent, View view, int pos, long id)      
{
Map<String, String> s = data.get((int) id);
current = s.toString();

And then just beneath it do like this:

Intent i = new Intent(MylistTab.this, SearchTab.class);
i.putExtra("var1", current);
startActivity(i);

And in the next acitvity:

current = getIntent().getExtras().getString("var1");

Why is this not possible? When i do like this and run the app delete wont work saying there is a nullpointexception somewhere in mylisttab and i will get transferred around the layouts(which i dont want). Has it to do with intent-filters? Im not sure I have to use them in this scenario.

4

1 回答 1

0

Glad to hear you are embarking the Android world. Let me start by saying it is fascinating.

Answering your question, may I ask if you have any constraints for your homework? I see you have hard coded your inputs in the java files. You can (and i recommend) defining all of your screen widgets (buttons, inputs, images, etc) in a xml layout and inflate them on activity's onCreate method.

Example taken from Ioshed (Google IO app)

XML (my_activity.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView android:id="@+id/choose_account_intro"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp" />
</LinearLayout>

Java (MyActivity.java)

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
}

Also, you could use the Fragments API which, to my understanding, is the correct way to make apps nowadays. Fragments help you modularize parts of your app's ui and behavior by creating small compoments that can be link via an activity.

Hope it helps.

于 2012-10-22T18:12:22.920 回答