ParseQueryAdapter を使用してリストビューにデータをロードしています。ある種のチャットにリストビューを使用しています。しかし、ListView をスクロールすると、レイアウトが完全に台無しになります。以下は、すべてのデータをロードした直後の、最初からチャットがどのように見えるかのスクリーンショットです。
これは、数回上下にスクロールした後の外観です。
「ViewHolderパターンを使用する」のような同様の問題と回答をすでに見ましたが、最初から使用していましたが、これは役に立ちませんでした。また、ListView match_parent の幅と高さを作成しました。これは、ラップ コンテンツがビュー アイテムを取得するのを台無しにすることがわかったからです。
ListView 項目を設定する場所であるため、問題は AsyncTask にある可能性があると思います。アダプターのコードは次のとおりです。
public class ChatParseQueryAdapter extends ParseQueryAdapter<Message> {
Activity activity;
String lighterID;
String lighterColor;
public ChatParseQueryAdapter(Context context, final String lighterID, String lighterColor){
super(context, new QueryFactory<Message>() {
@Override
public ParseQuery<Message> create() {
ParseQuery<Message> query = new ParseQuery<>("Message");
query.orderByAscending("createdAt");
query.whereEqualTo("lighter", ParseObject.createWithoutData("Lighter", lighterID));
query.include("user");
return query;
}
});
activity = (Activity) context;
this.lighterID = lighterID;
this.lighterColor = lighterColor;
}
@Override
public View getItemView(Message message, View v, ViewGroup parent) {
final ViewHolder viewHolder;
if (v == null){
v = View.inflate(getContext(), R.layout.message_list_item, null);
viewHolder = new ViewHolder();
viewHolder.messageDate = (TextView) v.findViewById(R.id.message_date);
viewHolder.otherUserImage = (ImageView) v.findViewById(R.id.message_other_user_image);
viewHolder.otherUserName = (TextView) v.findViewById(R.id.message_other_user_name);
viewHolder.messageTextLayout = (RelativeLayout) v.findViewById(R.id.message_text_layout);
viewHolder.messageText = (TextView) v.findViewById(R.id.message_text);
viewHolder.messageImage = (ImageView) v.findViewById(R.id.message_picture);
viewHolder.userImage = (ImageView) v.findViewById(R.id.message_user_image);
viewHolder.userName = (TextView) v.findViewById(R.id.message_user_name);
v.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) v.getTag();
}
new GetMessage(viewHolder).execute(message);
return super.getItemView(message, v, parent);
}
static class ViewHolder {
TextView messageDate;
ImageView otherUserImage;
TextView otherUserName;
RelativeLayout messageTextLayout;
TextView messageText;
ImageView messageImage;
ImageView userImage;
TextView userName;
}
class GetMessage extends AsyncTask<Message, Void, ChatMessage> {
ViewHolder viewHolder;
Resources resources;
public GetMessage(ViewHolder viewHolder){
this.viewHolder = new ViewHolder();
this.viewHolder = viewHolder;
resources = activity.getResources();
}
@Override
protected ChatMessage doInBackground(Message... params) {
if (isCancelled()){
cancel(true);
return null;
}
Message message = params[0];
ChatMessage result = new ChatMessage();
ParseUser messageAuthor = message.getUser();
String userProfileID = null;
String userName = null;
if (messageAuthor != null) {
userProfileID = messageAuthor.getString("profileID");
userName = messageAuthor.getString("name").toUpperCase();
}
result.setIsOtherMessage(messageAuthor != AppDelegate.getUser());
Bitmap bitmap = GraphicsHelper.getBitmap(userProfileID, messageAuthor, activity);
result.setUserImage(GraphicsHelper.getRoundedBitmap(bitmap));
result.setUserName(userName);
String messageText = message.getContent();
if (messageText != null){
result.setMessage(messageText);
} else {
result.setMessageImage(getParseImage(message));
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yy");
String date = simpleDateFormat.format(Date.parse(message.getCreatedAt().toString()));
result.setDate(date);
return result;
}
@Override
protected void onPostExecute(ChatMessage result) {
super.onPostExecute(result);
if (result != null && !isCancelled()){
if (result.isOtherMessage()){
viewHolder.userImage.setVisibility(View.GONE);
viewHolder.userName.setVisibility(View.GONE);
// Drawable drawable = resources.getDrawable(R.drawable.black_other_chat);
viewHolder.messageTextLayout.setBackgroundResource(R.drawable.black_other_chat);
// viewHolder.messageTextLayout.setBackground(drawable);
viewHolder.otherUserImage.setImageBitmap(result.getUserImage());
viewHolder.otherUserName.setText(result.getUserName());
} else {
viewHolder.otherUserImage.setVisibility(View.GONE);
viewHolder.otherUserName.setVisibility(View.GONE);
// Drawable drawable = activity.getResources().getDrawable(R.drawable.black_my_chat);
viewHolder.messageTextLayout.setBackgroundResource(R.drawable.black_my_chat);
// viewHolder.messageTextLayout.setBackground(drawable);
viewHolder.userImage.setImageBitmap(result.getUserImage());
viewHolder.userName.setText(result.getUserName());
viewHolder.messageText.setTextColor(GraphicsHelper.getAnotherColor(lighterColor, activity.getResources()));
}
String messageText = result.getMessage();
if (messageText != null){
viewHolder.messageDate.setText(result.getDate());
viewHolder.messageImage.setVisibility(View.GONE);
viewHolder.messageText.setText(result.getMessage());
} else {
viewHolder.messageDate.setVisibility(View.GONE);
viewHolder.messageText.setVisibility(View.GONE);
viewHolder.messageImage.setImageBitmap(result.getMessageImage());
}
}
}
private Bitmap getParseImage (Message message){
Bitmap bitmap = null;
byte[] imageByteArray;
if (message != null){
ParseFile imageFile = (ParseFile) message.get("info");
try {
imageByteArray = imageFile.getData();
bitmap = BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length);
// int dimension = GraphicsHelper.getSquareCropDimensionForBitmap(bitmap);
// bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension);
} catch (ParseException | NullPointerException e1) {
// e1.printStackTrace();
}
}
return bitmap;
}
}
}
これは私のチャットフラグメントコードです:
public class FragmentChat extends Fragment {
String lighterID;
String lighterColor;
ListView chatListView;
View globalView;
ChatParseQueryAdapter mainAdapter;
ApplicationInterface fragmentHolder;
public FragmentChat(String lighterID, String lighterColor){
this.lighterID = lighterID;
this.lighterColor = lighterColor;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
fragmentHolder = (ApplicationInterface) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString());
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_chat, container, false);
globalView = view;
new SetUpChatTitle(view).execute(0);
chatListView = (ListView) view.findViewById(R.id.chat_list_view);
// chatListView.setOnScrollListener(new AbsListView.OnScrollListener() {
// @Override
// public void onScrollStateChanged(AbsListView view, int scrollState) {
//
// }
//
// @Override
// public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//
// }
// });
mainAdapter = new ChatParseQueryAdapter(getActivity(), lighterID, lighterColor);
chatListView.setAdapter(mainAdapter);
RelativeLayout chatLayout = (RelativeLayout) view.findViewById(R.id.chat_layout);
chatLayout.setBackgroundColor(GraphicsHelper.getColor(lighterColor, getResources()));
// EditText chatInputMessage = (EditText) view.findViewById(R.id.chat_input_message);
// chatInputMessage.setBackgroundResource(R.drawable.round_corners_layout);
// GradientDrawable inputMessageDrawable = (GradientDrawable) chatInputMessage.getBackground();
// inputMessageDrawable.setColor(getResources().getColor(R.color.white));
// inputMessageDrawable.setStroke(4, GraphicsHelper.getAnotherColor(lighterColor, resources));
// inputMessageDrawable.setCornerRadius(40);
//
// Button sendMessageButton = (Button) view.findViewById(R.id.chat_send_message);
// sendMessageButton.setBackgroundResource(R.drawable.round_corners_layout);
// GradientDrawable sendMessageDrawable = (GradientDrawable) sendMessageButton.getBackground();
// sendMessageDrawable.setColor(GraphicsHelper.getAnotherColor(lighterColor, resources));
// sendMessageDrawable.setCornerRadius(30);
return view;
}
class SetUpChatTitle extends AsyncTask<Integer, Void, RankingItem> {
View view;
HorizontalScrollView chatTitleScrollView;
RelativeLayout lighterNameAndMilesLayout;
TextView rank;
TextView lighterName;
TextView milesTravelled;
ImageView userImage;
LinearLayout enterMessageLayout;
EditText chatInputMessage;
Button sendMessageButton;
ImageView attachPictureButton;
public SetUpChatTitle(View view){
this.view = view;
chatTitleScrollView = (HorizontalScrollView) view.findViewById(R.id.chat_title_scroll_view);
lighterNameAndMilesLayout = (RelativeLayout) view.findViewById(R.id.chat_lighter_name_and_miles_layout);
rank = (TextView) view.findViewById(R.id.chat_rank_number);
lighterName = (TextView) view.findViewById(R.id.chat_lighter_name);
milesTravelled = (TextView) view.findViewById(R.id.chat_lighter_miles_travelled);
userImage = (ImageView) view.findViewById(R.id.chat_user_image);
enterMessageLayout = (LinearLayout) view.findViewById(R.id.chat_message_layout);
chatInputMessage = (EditText) view.findViewById(R.id.chat_input_message);
sendMessageButton = (Button) view.findViewById(R.id.chat_send_message);
attachPictureButton = (ImageView) view.findViewById(R.id.chat_attach_picture_button);
}
@Override
protected RankingItem doInBackground(Integer... params) {
if (isCancelled()){
cancel(true);
return null;
}
RankingItem result = new RankingItem();
ParseQuery<ParseObject> lighterQuery = ParseQuery.getQuery("Lighter");
try {
Lighter lighter = (Lighter) lighterQuery.get(lighterID);
result.setLighterName(lighter.getLighterName().toUpperCase());
result.setMilesTravelled(String.valueOf(lighter.getIntMiles()) + " MILES TRAVELLED");
ParseUser lastUser = lighter.getMaster();
String profileID = null;
if (lastUser != null) {
lastUser.fetchIfNeeded();
profileID = lastUser.getString("profileID");
}
Bitmap bitmap = GraphicsHelper.getBitmap(profileID, lastUser, getActivity());
result.setUserImage(GraphicsHelper.getBitmapWithTineCircle(bitmap, getActivity()));
lighterQuery.whereGreaterThanOrEqualTo("miles", lighter.getDouble("miles"));
result.setRank("#" + lighterQuery.count());
JSONArray userList = lighter.getJSONArray("users");
String parseUserObjectId = AppDelegate.getUser().getObjectId();
boolean userChat = false;
for (int i = 0; i < userList.length(); i++){
if (userList.getJSONObject(i).getString("objectId").equals(parseUserObjectId)) {
userChat = true;
}
}
result.setUserChat(userChat);
} catch (ParseException | JSONException e) {
e.printStackTrace();
}
return result;
}
@Override
protected void onPostExecute(RankingItem result) {
super.onPostExecute(result);
if (result != null && !isCancelled()){
GraphicsHelper.setUpChatTitle(view, lighterColor, getActivity());
lighterNameAndMilesLayout.getLayoutParams().width = GraphicsHelper.getScreenSize(getActivity()).x - FragmentMap.MARGIN;
chatTitleScrollView.setSmoothScrollingEnabled(true);
globalView.post(new Runnable() {
@Override
public void run() {
chatTitleScrollView.fullScroll(View.FOCUS_RIGHT);
}
});
rank.setText(result.getRank());
lighterName.setText(result.getLighterName());
milesTravelled.setText(result.getMilesTravelled());
userImage.setImageBitmap(result.getUserImage());
final GestureDetector gestureDetector = new GestureDetector(
new GestureDetectorTwoPositions(1, chatTitleScrollView));
chatTitleScrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
});
chatTitleScrollView.setVisibility(View.VISIBLE);
if (result.isUserChat()){
Resources resources = getResources();
chatInputMessage.setBackgroundResource(R.drawable.round_corners_layout);
GradientDrawable inputMessageDrawable = (GradientDrawable) chatInputMessage.getBackground();
inputMessageDrawable.setColor(getResources().getColor(R.color.white));
inputMessageDrawable.setStroke(4, GraphicsHelper.getAnotherColor(lighterColor, resources));
inputMessageDrawable.setCornerRadius(40);
sendMessageButton.setBackgroundResource(R.drawable.round_corners_layout);
GradientDrawable sendMessageDrawable = (GradientDrawable) sendMessageButton.getBackground();
sendMessageDrawable.setColor(GraphicsHelper.getAnotherColor(lighterColor, resources));
sendMessageDrawable.setCornerRadius(30);
sendMessageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String inputMessage = chatInputMessage.getText().toString().trim();
if (TextUtils.isEmpty(inputMessage)) {
LoginActivity.showAlertDialog(getString(R.string.enter_the_message), getActivity());
} else {
Message message = new Message();
message.setUser(AppDelegate.getUser());
message.setPublicReadWriteAcl();
message.setLighter(ParseObject.createWithoutData("Lighter", lighterID));
Location currentLocation = LocationInfo.getBestLocation(getActivity());
ParseGeoPoint location = new ParseGeoPoint(currentLocation.getLatitude(), currentLocation.getLongitude());
message.setLocation(location);
message.setContent(inputMessage);
message.setType(1d);
message.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
mainAdapter.notifyDataSetChanged();
chatListView.setAdapter(mainAdapter);
}
});
}
}
});
enterMessageLayout.setVisibility(View.VISIBLE);
attachPictureButton.setVisibility(View.VISIBLE);
}
}
}
public void receiveMessage(){
}
}
}
そして、これは私の ListView xml コードがどのように見えるかです:
<ListView
android:id="@+id/chat_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:dividerHeight="0dp"
android:divider="@null"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
android:layout_marginBottom="@dimen/double_margin"
android:layout_below="@id/chat_title_scroll_view"
android:layout_above="@+id/chat_message_layout"/>
前もって感謝します。