我昨天发布了一个关于我的listview问题的问题。列表视图中的图像按钮状态未保存(它已重置为默认状态(未选中))。
无论我尝试了多少,我都无法解决它。
现在Rigt,我遇到了单身人士的问题:
我想在“对象”图像按钮被“检查”时从行对象中保存字符串并将其发送到单个ArrayList<String>
。
奇怪的是,ArrayList最多只包含一个元素,它甚至可以“刷新”(删除所有对象)而不会被提示。
MainActivity(包含SINGLEETON !!!)
package com.example.geostocks;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.json.JSONArray;
import org.json.JSONException;
import com.example.geostocks.R;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.SearchView;
/* MainActivity.
* Made by: Joakim Bajoul Kakaei (881129-0298)
* Description: Creates and sets up the MainActivity programmatically.
* It is mainly associated with activity_main.xml, but uses the
* listview_layout.xml in connection to it.
*
* The idea was to keep the class as "clean" as possible and use
* multiple classes to help making coding and efficiency more easier.
*/
public class MainActivity extends Activity {
public static ArrayList<String> checkedCompanies = new ArrayList<String>();
public Menu m; // Variable to store a menu-item as a public variable.
// This helps with data allocation; instead of declaring the
// searchview and searchmanager in the creation of the
// application,
// it will wait to do it once the user decides to start the
// search.
// an array to store all jsonobjects in.
private JSONArray companies;
// an arraylist to store multiple companyobjects created later.
private List<companiesBuilder> allCompanies = new ArrayList<companiesBuilder>();
/*
* (non-Javadoc)
*
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
/*
* executes the AsyncTask (top10). When the task is executed, it
* then gets the JSONArray which is bouncing around.
*/
companies = new top10().execute("DO IT!").get();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ExecutionException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
/*
* The following snippet mainly creates the adapterobject and associates
* it with it's elements, context and layout.
*/
final ListView companyList = (ListView) findViewById(R.id.listView);
final companiesAdapter compAdp = new companiesAdapter(this,
R.layout.listview_layout);
System.out.println("after"); // debugging
/*
* a loop to create companyBuilder-objects from the JSONArray and then
* add those objects to an ArrayList (allCompanies).
*/
for (int i = 0; companies.length() > i; i++) {
System.out.println("companies-looper"); // debugging
System.out.println(companies.length()); // debugging
try {
System.out.println(companies.getJSONObject(i)); // debugging
allCompanies.add(new companiesBuilder(companies
.getJSONObject(i)));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* this loop goes through every company that has been built and adds it
* to the custom listview adapter.
*/
for (companiesBuilder built : allCompanies) {
compAdp.add(built);
}
companyList.setAdapter(compAdp);
}
/*
* (non-Javadoc)
*
* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
m = menu; // adds a reference to the variable m (menu).
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return (super.onCreateOptionsMenu(menu)); // returns the super for
// efficiency.
}
/*
* (non-Javadoc)
*
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
openSearch(); // when searchbutton is clicked, it will start the
// opensearch method.
return true;
case R.id.action_settings:
// openSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/*
* Written by: Joakim Bajoul Kakaei Description: Invoked when user presses
* search icon. Opens up the searchview in the menu.
*/
public void openSearch() {
/*
* snippet taken from
* http://developer.android.com/training/search/setup.html with some
* changes to it.
*/
SearchManager sm = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView sv = (SearchView) m.findItem(R.id.search).getActionView();
sv.setSearchableInfo(sm.getSearchableInfo(getComponentName()));
}
/*
* top10 (AsyncTask) Name: Joakim Bajoul Kakaei (881129-0298) Description:
* This class handles the connection between the JSONparser and the
* mainActivity using a different thread. It's mainly used to help with
* memory allocation as well as making sure the main-thread isn't too
* overloaded with too many assignments.
*/
private class top10 extends AsyncTask<String, String, JSONArray> {
@Override
protected JSONArray doInBackground(String... params) {
JSONparser jparser = new JSONparser();
companies = jparser.topCompanies();
System.out.println("background"); // debugging
return companies;
}
@Override
protected void onPostExecute(JSONArray jarr) {
System.out.println("onpost");
}
}
}
SearchActivity(此处调用onBackPressed()以显示单例中的所有元素)
package com.example.geostocks;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.json.JSONArray;
import org.json.JSONException;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.ListView;
public class SearchActivity extends Activity {
JSONArray companies;
String query;
private List<companiesBuilder> allCompanies = new ArrayList<companiesBuilder>();
companiesAdapter compAdp;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
handleIntent(getIntent());
try {
/*
* executes the AsyncTask (top10). When the task is executed, it
* then gets the JSONArray which is bouncing around.
*/
companies = new searchList().execute("DO IT!").get();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ExecutionException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
/*
* The following snippet mainly creates the adapterobject and associates
* it with it's elements, context and layout.
*/
final ListView companyList = (ListView) findViewById(R.id.listView_search);
compAdp = new companiesAdapter(this, R.layout.listview_layout);
System.out.println("after"); // debugging
/*
* a loop to create companyBuilder-objects from the JSONArray and then
* add those objects to an ArrayList (allCompanies).
*/
for (int i = 0; companies.length() > i; i++) {
System.out.println("companies-looper"); // debugging
System.out.println(companies.length()); // debugging
try {
System.out.println(companies.getJSONObject(i)); // debugging
allCompanies.add(new companiesBuilder(companies
.getJSONObject(i)));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* this loop goes through every company that has been built and adds it
* to the custom listview adapter.
*/
for (companiesBuilder built : allCompanies) {
for (int i = 0; i < MainActivity.checkedCompanies.size(); i++) {
System.out.println("CHECKED" + MainActivity.checkedCompanies.get(i));
if (MainActivity.checkedCompanies.get(i).equals(built.getSymbol())) {
built.setSelect(true);
}
}
compAdp.add(built);
}
companyList.setAdapter(compAdp);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
super.onBackPressed();
System.out.println(MainActivity.checkedCompanies.size());
System.out.println("BACK PRESSED!");
for (int i = 0; i < MainActivity.checkedCompanies.size(); i++) {
System.out.println("CHECKED" + MainActivity.checkedCompanies.get(i));
}
}
return true;
}
@Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
query = intent.getStringExtra(SearchManager.QUERY);
System.out.println(query);
// use the query to search your data somehow
}
}
private class searchList extends AsyncTask<String, String, JSONArray> {
@Override
protected JSONArray doInBackground(String... params) {
JSONparser jparser = new JSONparser();
companies = jparser.search(query);
System.out.println("background"); // debugging
return companies;
}
@Override
protected void onPostExecute(JSONArray jarr) {
System.out.println("onpost");
}
}
}
CompaniesAdapter(我有一个onClickListener到ImageButton,它试图 操纵单身人士):
package com.example.geostocks;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
/* companiesAdapter.
* Made by: Joakim Bajoul Kakaei (881129-0298)
* Description: Since the listview we have decided to use has multiple objects on each row,
* the listview's adapter needs to be customized to meet those requirements.
* This class may be revised later on (to add or remove objects from the rowItemObjects).
*/
public class companiesAdapter extends ArrayAdapter<companiesBuilder> implements
OnClickListener {
private final int companiesBuilderResource;
private ArrayList<companiesBuilder> companies;
private static ArrayList<String> checked = new ArrayList<String>();
public companiesAdapter(final Context context,
final int companiesBuilderResource) {
super(context, 0);
this.companiesBuilderResource = companiesBuilderResource;
companies = new ArrayList<companiesBuilder>();
}
public void addChecked(String symbol) {
MainActivity.checkedCompanies.add(symbol);
}
public void removeChecked(String symbol) {
MainActivity.checkedCompanies.remove(symbol);
}
public void add(companiesBuilder row) {
companies.add(row);
notifyDataSetChanged();
}
@Override
public int getCount() {
return companies.size();
}
@Override
public companiesBuilder getItem(int i) {
return companies.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(final int position, final View convertView,
final ViewGroup parent) {
// We need to get the best view (re-used if possible) and then
// retrieve its corresponding rowItem, to optimize lookup efficiency.
final View view = getourView(convertView);
final rowItem rowItem = getrowItem(view);
// final companiesBuilder company = getItem(position);
final companiesBuilder row = companies.get(position);
// Setting up both the titleobject's with their corresponding variables
// (from the row-object).
rowItem.titleView_left.setText(row.getName());
rowItem.titleView_right.setText(row.getPrice());
// Setting up the subtitle's items will be a little bit tougher, since
// it requires
// some manipulating of the xml-data.
rowItem.subTitleView_left.setText(row.getSymbol());
/*
* If-clauses to change the right subtitle's color palette to make it
* easier for the user to distinguish increase and decrease.
*/
if (Double.parseDouble(row.getChange()) < 0) {
rowItem.subTitleView_right
.setTextColor(Color.parseColor("#E51400"));
rowItem.subTitleView_right.setText(row.getPercent() + "%" + " "
+ "( " + row.getChange() + ")");
} else if (Double.parseDouble(row.getChange()) > 0) {
rowItem.subTitleView_right
.setTextColor(Color.parseColor("#339933"));
rowItem.subTitleView_right.setText(row.getPercent() + "%" + " "
+ "( +" + row.getChange() + ")");
} else {
rowItem.subTitleView_right.setText(row.getPercent() + "%" + " "
+ "(" + row.getChange() + ")");
}
// Setting image view is simple enough...
for (int i = 0; checked.size() > i; i++) {
System.out.println("CHECKED" + checked.get(i));
}
rowItem.imageButton.setSelected(row.getSelected());
view.setOnClickListener(new OnClickListener() {
/*
* Add an onClickListener that is associated with view (view being
* every row).
*/
@Override
public void onClick(View v) {
new AlertDialog.Builder(getContext()).setTitle(row.getName())
.show();
}
});
rowItem.imageButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View button) {
if (button.isSelected()) {
button.setSelected(false);
addChecked(row.getSymbol());
} else {
button.setSelected(true);
removeChecked(row.getSymbol());
}
row.setSelect(view.isSelected());
for (int i = 0; MainActivity.checkedCompanies.size() > i; i++) {
System.out.println("CHECKEDLOOP"
+ MainActivity.checkedCompanies.get(i));
}
}
});
return view;
}
private View getourView(final View convertView) {
// The ourView will be recycling / reusing the convertview if
// possible.
// Guess why? Exactly. CUZ WE LOOOOOOOOOOVE HAVING EFFICIENT CODE! <3
View ourView = null;
if (null == convertView) {
final Context context = getContext();
final LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ourView = inflater.inflate(companiesBuilderResource, null);
} else {
ourView = convertView;
}
return ourView;
}
private rowItem getrowItem(final View ourView) {
// Recycling and reusing tags and objects is the name of the game!
final Object tag = ourView.getTag();
rowItem rowItem = null;
/*
* Sets up the listview's rowitems with their corresponding listview
* items (textviews and images).
*/
if (null == tag || !(tag instanceof rowItem)) {
rowItem = new rowItem();
rowItem.titleView_right = (TextView) ourView
.findViewById(R.id.title_right);
rowItem.titleView_left = (TextView) ourView
.findViewById(R.id.title_left);
rowItem.subTitleView_left = (TextView) ourView
.findViewById(R.id.subtitle_left);
rowItem.subTitleView_right = (TextView) ourView
.findViewById(R.id.subtitle_right);
rowItem.imageButton = (ImageButton) ourView
.findViewById(R.id.add_button);
ourView.setTag(rowItem);
} else {
rowItem = (rowItem) tag;
}
return rowItem;
}
/*
* since views are recycled, these references will always be there to be
* reused. Again, it's all about optimization!
*/
private static class rowItem {
public TextView titleView_left;
public TextView titleView_right;
public TextView subTitleView_left;
public TextView subTitleView_right;
public ImageButton imageButton;
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
我还尝试使用全局变量,因为我使用了一个带有application = name的类。 但是,我不能在适配器中使用该类。这反过来使我无法操纵所述全局变量,因为缺少上下文。
这是全球类:
package com.example.geostocks;
import java.util.ArrayList;
import android.app.Application;
public class checkedCompanies extends Application{
private ArrayList<companiesBuilder> checked = new ArrayList<companiesBuilder>();
public ArrayList<companiesBuilder> get() {
return checked;
}
public void set(companiesBuilder built) {
checked.add(built);
}
public void remove(companiesBuilder removeIndex){
checked.remove(removeIndex);
}
}