0

我正在使用 ParseQueryAdapter 将数据加载到我的列表视图中。我正在使用 listview 进行某种聊天。但是当我滚动 ListView 时,它完全搞乱了布局。这是加载所有数据后聊天从一开始时的屏幕截图: 从一开始就聊天

这就是我上下滚动几次后的样子: 滚动后聊天

我已经看到了类似的问题和答案,例如:“使用 ViewHolder 模式”但是我从一开始就使用它,这没有帮助。我还制作了 ListView match_parent 的宽度和高度,因为我看到包装内容弄乱了查看项目。

我假设我的问题可能出在 AsyncTask 中,因为它是我设置 ListView 项目的地方。这是适配器的代码:

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"/>

先感谢您。

4

1 回答 1

1

试试这个:在你的适配器类中覆盖这两个方法:

    @Override
  public int getViewTypeCount() {

   return 1;
  }

  @Override
  public int getItemViewType(int position) {

   return position;
  }

您还可以看到:List view items changes position when scrolling android?

编辑 的 Adater 类的getItemView()方法一次又一次地被调用,而你正在asyncTask从这个方法调用你的(运行缓慢),即不是好方法。您需要asyncTask从您的片段类中调用,然后从onPostExecute()您的 asyncTask 中调用适配器类。

于 2015-05-22T11:35:49.520 回答