我正在尝试解决问题2天,但没有成功。我正在使用SimpleCursorAdapter将消息加载到ListView。每个ListView行都需要有计数器。我有计数器的问题,我不能使它在SimpleCursorAdapter.setViewBinder中工作。这是我的代码:
public class ChatActivity extends BaseActivity implements LoaderManager.LoaderCallbacks<Cursor>
{
private ListView chatScreen;
private SimpleCursorAdapter adapter;
private String sender;
private String receiver;
@Override public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayUseLogoEnabled(false);
getSupportActionBar().setDisplayShowTitleEnabled(true);
onNewIntent(getIntent());
chatScreen = (ListView) findViewById(R.id.lv);
chatScreen.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
adapter = new SimpleCursorAdapter(
this,
R.layout.activity_chat_message,
null,
new String[]{DataProvider.COL_MSG, DataProvider.COL_AT},
new int[]{R.id.chat_message, R.id.chat_date},
0);
adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
LinearLayout root = (LinearLayout) view.getParent().getParent();
TextView text = (TextView) root.findViewById(R.id.chat_counter);
int position = chatScreen.getPositionForView(text);
text.setText("60");
text.setTag(position);
final Handler mClockHandler = new Handler();
mUpdateClockTask clockTask = new mUpdateClockTask(text, text.getTag().toString());
mClockHandler.post(clockTask);
switch(view.getId()) {
case R.id.chat_message:
LinearLayout chatMessage = (LinearLayout) root.findViewById(R.id.chatSingleMessage);
if (cursor.getString(cursor.getColumnIndex(DataProvider.COL_FROM)) == null) {
root.setGravity(Gravity.RIGHT);
root.setPadding(50, 10, 10, 10);
chatMessage.setBackgroundResource(R.drawable.cloud_bubble_green);
} else {
root.setGravity(Gravity.LEFT);
root.setPadding(10, 10, 50, 10);
chatMessage.setBackgroundResource(R.drawable.cloud_bubble_blue);
}
break;
}
return false;
}
});
chatScreen.setAdapter(adapter);
getLoaderManager().initLoader(0, null, this);
chatScreen.getFirstVisiblePosition();
final EmojiconEditText emojiconEditText = (EmojiconEditText) findViewById(R.id.emojicon_edit_text);
final View rootView = findViewById(R.id.root_view);
final RelativeLayout rootSend = (RelativeLayout) findViewById(R.id.root_send);
final ImageView emojiButton = (ImageView) findViewById(R.id.emoji_btn);
final ImageView submitButton = (ImageView) findViewById(R.id.submit_btn);
// Give the topmost view of your activity layout hierarchy. This will be used to measure soft keyboard height
final EmojiconsPopup popup = new EmojiconsPopup(rootView, this);
//Will automatically set size according to the soft keyboard size
popup.setSizeForSoftKeyboard();
//Set on emojicon click listener
popup.setOnEmojiconClickedListener(new EmojiconGridView.OnEmojiconClickedListener() {
@Override
public void onEmojiconClicked(Emojicon emojicon) {
emojiconEditText.append(emojicon.getEmoji());
}
});
//Set on backspace click listener
popup.setOnEmojiconBackspaceClickedListener(new EmojiconsPopup.OnEmojiconBackspaceClickedListener() {
@Override
public void onEmojiconBackspaceClicked(View v) {
KeyEvent event = new KeyEvent(
0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
emojiconEditText.dispatchKeyEvent(event);
}
});
//If the emoji popup is dismissed, change emojiButton to smiley icon
popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
changeEmojiKeyboardIcon(emojiButton, R.drawable.smiley);
}
});
//If the text keyboard closes, also dismiss the emoji popup
popup.setOnSoftKeyboardOpenCloseListener(new EmojiconsPopup.OnSoftKeyboardOpenCloseListener() {
@Override
public void onKeyboardOpen(int keyBoardHeight) {
}
@Override
public void onKeyboardClose() {
if(popup.isShowing())
popup.dismiss();
}
});
//On emoji clicked, add it to edittext
popup.setOnEmojiconClickedListener(new EmojiconGridView.OnEmojiconClickedListener() {
@Override
public void onEmojiconClicked(Emojicon emojicon) {
emojiconEditText.append(emojicon.getEmoji());
}
});
//On backspace clicked, emulate the KEYCODE_DEL key event
popup.setOnEmojiconBackspaceClickedListener(new EmojiconsPopup.OnEmojiconBackspaceClickedListener() {
@Override
public void onEmojiconBackspaceClicked(View v) {
KeyEvent event = new KeyEvent(
0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
emojiconEditText.dispatchKeyEvent(event);
}
});
// To toggle between text keyboard and emoji keyboard keyboard(Popup)
emojiButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//If popup is not showing => emoji keyboard is not visible, we need to show it
if(!popup.isShowing()){
//If keyboard is visible, simply show the emoji popup
if(popup.isKeyBoardOpen()){
popup.showAtBottom();
changeEmojiKeyboardIcon(emojiButton, R.drawable.ic_action_keyboard);
}
//else, open the text keyboard first and immediately after that show the emoji popup
else{
emojiconEditText.setFocusableInTouchMode(true);
emojiconEditText.requestFocus();
popup.showAtBottomPending();
final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(emojiconEditText, InputMethodManager.SHOW_FORCED);
changeEmojiKeyboardIcon(emojiButton, R.drawable.ic_action_keyboard);
}
}
//If popup is showing, simply dismiss it to show the undelying text keyboard
else{
popup.dismiss();
}
}
});
//On submit, add the edittext text to listview and clear the edittext
submitButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String newText = emojiconEditText.getText().toString();
if(!connectionDetector.isConnectedToInternet())
displayConnectionAlert("Cellular Data is Off","Enable your data pockets or wifi");
else
{
if(!newText.equals("") && newText.trim().length() > 0)
send(newText);
}
emojiconEditText.getText().clear();
}
});
}
private void changeEmojiKeyboardIcon(ImageView iconToBeChanged, int drawableResourceId){
iconToBeChanged.setImageResource(drawableResourceId);
}
@Override public Loader<Cursor> onCreateLoader(int loader, Bundle bundle) {
String[] projection = { DataProvider.KEY_ID, DataProvider.COL_MSG, DataProvider.COL_FROM, DataProvider.COL_TO, DataProvider.COL_AT};
CursorLoader cursorLoader = new CursorLoader(this,
DataProvider.CONTENT_URI_MESSAGES, projection, null, null, null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
@Override public void onNewIntent(Intent i)
{
Bundle bundle = i.getExtras();
sender = bundle.getString("sender");
receiver = bundle.getString("receiver");
String receiver_name = bundle.getString("receiver_name");
getSupportActionBar().setTitle(receiver_name);
Log.e("SENDER", sender);
//Log.e("RECEIVER NAME", receiver_name);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(menu.findItem(4) == null) {
menu.add(R.id.main_menu, 4, Menu.NONE, "Shutdown").setIcon(R.drawable.shutdown).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
MenuItem contacts = menu.findItem(R.id.action_contacts);
contacts.setVisible(false);
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case R.id.action_contacts:
Intent toContacts = new Intent(this, ContactsActivity.class);
startActivity(toContacts);
break;
case 4:
DatabaseHandler dbH = new DatabaseHandler(getApplicationContext());
dbH.deleteMessages();
Toast.makeText(getApplicationContext(), "Messages Deleted", Toast.LENGTH_SHORT).show();
adapter.notifyDataSetChanged();
getLoaderManager().restartLoader(0, null, this);
break;
case R.id.action_logout:
if(mGoogleApiClient.isConnected())
{
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
}
else if(Session.getActiveSession().isOpened())
Session.getActiveSession().closeAndClearTokenInformation();
Intent logout = new Intent(this, LoginActivity.class);
startActivity(logout);
finish();
break;
}
return super.onOptionsItemSelected(item);
}
private void send(final String message)
{
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String msg = "";
String result = new HttpSender("http://178.62.0.225/sup/public/api/sup/message", "POST")
.sendMessage(message, sender, receiver);
Log.e("MESSAGE RESULT", result);
ContentValues values = new ContentValues(2);
values.put(DataProvider.COL_MSG, message);
values.put(DataProvider.COL_TO, receiver);
values.put(DataProvider.COL_AT, new SimpleDateFormat("HH:mm").format(Calendar.getInstance().getTime()));
getContentResolver().insert(DataProvider.CONTENT_URI_MESSAGES, values);
return msg;
}
@Override
protected void onPostExecute(String msg) {
if (!TextUtils.isEmpty(msg)) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
}
}.execute(null, null, null);
}
/*@Override public void onStop()
{
DatabaseHandler dbH = new DatabaseHandler(getApplicationContext());
dbH.deleteMessages();
super.onStop();
}*/
@Override public void onDestroy()
{
DatabaseHandler dbH = new DatabaseHandler(getApplicationContext());
dbH.deleteMessages();
super.onDestroy();
}
@Override public void onConnected(Bundle connectionHint){}
public class mUpdateClockTask implements Runnable {
private TextView tv;
final Handler mClockHandler = new Handler();
String tag;
public mUpdateClockTask(TextView tv,String tag) {
this.tv = tv;
this.tag = tag;
}
public void run() {
if (tv.getTag().toString().equals(tag)) {
// do what ever you want to happen every second
int counter_value = Integer.parseInt(tv.getText().toString());
if(counter_value > 0)
{
counter_value -= 1;
tv.setText(String.valueOf(counter_value));
}
else
{
getContentResolver().delete(DataProvider.CONTENT_URI_MESSAGES, "_id=?", new String[]{String.valueOf(tag)});
}
mClockHandler.postDelayed(this, 1000);
}
}
};
}