帖子.java
public class Posts extends Activity implements OnCheckedChangeListener {
private static final String TAG = "POSTS";
private static final int NULL_COUNTRY_CODE = 6;
private static final int POST_BACK_BTN = 7;
private static final int CHANGE = 8;
private String un;
private SimpleAdapter simpleAdpt;
private EditText post;
private RadioGroup radGrp;
private GPSTracker mGPS;
private PullToRefreshListView lv;
private String initial = "Se eida ";
private String code;
private String unm;
private String postui;
private String tmp;
private String idPost;
// The data to show
private List<Map<String, String>> postsList = new ArrayList<Map<String, String>>();
JSONArray array = null;
private static List<String> list = new ArrayList<String>();
private String pst;
private AlertDialogFragments adf;
private FragmentTransaction ft;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_posts);
initLocation();
if (code == null) {
ft = getFragmentManager().beginTransaction();
// Create and show the dialog.
adf = new AlertDialogFragments(NULL_COUNTRY_CODE);
adf.show(ft, "dialog");
}
init();
}
private HashMap<String, String> createPost(String key, String name) {
HashMap<String, String> post = new HashMap<String, String>();
post.put(key, name);
return post;
}
private void initLocation() {
mGPS = new GPSTracker(this);
final double mLat = mGPS.getLatitude();
final double mLong = mGPS.getLongitude();
getAddress(mLat, mLong);
}
private void getAddress(double mLat, double mLong) {
try {
Geocoder gcd = new Geocoder(this, Locale.getDefault());
List<Address> addresses = gcd.getFromLocation(mLat, mLong, 100);
if (addresses.size() > 0) {
addresses = gcd.getFromLocation(mLat, mLong, 1);
code = addresses.get(0).getCountryCode();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void init() {
this.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Intent i = getIntent();
un = i.getStringExtra("un");
post = (EditText) findViewById(R.id.lbl_txt);
radGrp = (RadioGroup) findViewById(R.id.rdg);
radGrp.setOnCheckedChangeListener(this);
// We get the ListView component from the layout
lv = (PullToRefreshListView) findViewById(R.id.listView);
// Set a listener to be invoked when the list should be refreshed.
((PullToRefreshListView) lv)
.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
((PullToRefreshListView) lv)
.setLastUpdated(new SimpleDateFormat(
"dd-MM-yyyy HH:mm").format(new Date()));
new GetData().execute();
}
});
simpleAdpt = new CustomAdapter(this, postsList,
android.R.layout.simple_list_item_1, new String[] { "post" },
new int[] { android.R.id.text1 });
new GetData().execute();
}
public class CustomAdapter extends SimpleAdapter {
HashMap<String, String> map = new HashMap<String, String>();
public CustomAdapter(Context context,
List<? extends Map<String, String>> data, int resource,
String[] from, int[] to) {
super(context, data, resource, from, to);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
if (row != null) {
if (position % 2 == 0)
row.setBackgroundResource(R.drawable.listview_selector_even);
else
row.setBackgroundResource(R.drawable.listview_selector_odd);
}
return row;
}
}
private class GetData extends AsyncTask<String, String, String> {
private ProgressDialog progDailog;
@Override
protected void onPreExecute() {
super.onPreExecute();
progDailog = new ProgressDialog(Posts.this);
progDailog.setMessage("Loading...");
progDailog.setIndeterminate(false);
progDailog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progDailog.setCancelable(true);
progDailog.show();
}
@Override
protected String doInBackground(String... params) {
postsList.clear();
list.clear();
new Thread(new Runnable() {
public void run() {
//getting data from server and store into results
try {
array = new JSONArray(result);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < array.length(); i++) {
JSONObject row = null;
try {
row = array.getJSONObject(i);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
unm = row.getString("Username");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
postui = row.getString("Post");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
tmp = row.getString("Timestamp");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
idPost = row.getString("Id");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pst = unm + ":\n" + postui + "\n"
+ tmp.substring(0, tmp.length() - 2);
list.add(i, idPost);
postsList.add(createPost("post", pst));
}
runOnUiThread(new Runnable() {
@Override
public void run() {
lv.setSelector(R.drawable.row_pressed);
lv.setAdapter(simpleAdpt);
simpleAdpt.notifyDataSetChanged();
registerForContextMenu(lv);
}
});
}
}).start();
return null;
}
@Override
protected void onPostExecute(String unused) {
super.onPostExecute(unused);
simpleAdpt.notifyDataSetChanged();
progDailog.dismiss();
((PullToRefreshListView) lv).onRefreshComplete();
}
}
// We want to create a context Menu when the user long click on an item
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;
// We know that each row in the adapter is a Map
HashMap<?, ?> map = (HashMap<?, ?>) simpleAdpt
.getItem(aInfo.position - 1);
String string = (String) map.get("post");
menu.setHeaderTitle("Options");
menu.add(1, 1, 1, "Share via:");
menu.add(1, 2, 2, "Copy");
menu.add(1, 3, 3, "Delete");
menu.add(1, 1, 1, "Share via:");
menu.add(1, 2, 2, "Copy");
}
// This method is called when user selects an Item in the Context menu
@SuppressWarnings("deprecation")
@Override
public boolean onContextItemSelected(MenuItem item) {
int itemId = item.getItemId();
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
switch (itemId) {
case 1:
// Share intent
String key = ((TextView) info.targetView).getText().toString();
// create the send intent
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
// set the type
shareIntent.setType("text/plain");
// add a subject
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
R.string.app_name);
// build the body of the message to be shared
String shareMessage = key.substring(0, key.length() - 20)
.substring(key.indexOf(":") + 2);
// add the message
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT,
shareMessage);
// start the chooser for sharing
startActivity(Intent.createChooser(shareIntent, "Share via: "));
break;
case 2:
// Copy
String key1 = ((TextView) info.targetView).getText().toString();
int sdk = android.os.Build.VERSION.SDK_INT;
if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(key1.substring(0, key1.length() - 20)
.substring(key1.indexOf(":") + 2));
Toast.makeText(this, "Post copied.", Toast.LENGTH_SHORT).show();
} else {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData
.newPlainText("", key1.substring(0, key1.length() - 20)
.substring(key1.indexOf(":") + 2));
clipboard.setPrimaryClip(clip);
Toast.makeText(this, "Post copied.", Toast.LENGTH_SHORT).show();
}
break;
case 3:
// Delete
int index = info.position - 1;
//deletes a post
deletePost(list.get(index), this);
new GetData().execute();
break;
}
return true;
}
我的 Logcat 输出
适配器的内容发生了变化,但 ListView 没有收到通知。确保适配器的内容不是从后台线程修改的,而只是从 UI 线程修改的。