嗨,我是 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.