如何正确实现嵌套的recyclerview,child recyclerviews行为奇怪

时间:2017-12-27 04:56:08

标签: android android-recyclerview nestedrecyclerview

我正在开发一个聊天应用程序。聊天消息由普通文本消息组成,有时它可以是recyclerview中的项目列表。

所以我实现了嵌套Recyclerview。那么在json响应中会发生什么,如果消息只是普通文本,则会显示textview,但消息中包含一个URL,然后显示horizantal recyclerview代替textview。

问题是,如果在json响应中,假设有10条消息,那10条消息中有4条是URL,所以我应该看到6条正常文本和4条Recyclerviews。但是嵌套的recyclerview表现得非常奇怪,有时它甚至不显示,有时我可以看到2个Recyclerviews,有时4个但是有相同的URL(相同的项目列表)。

我不知道我做错了什么。有人可以看看代码并告诉我出了什么问题吗?

我的父(垂直)Recyclerview布局

    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="messageViewModel"
            type="com.sukshi.sukshichat.viewmodel.MessageFragmViewModel"/>
    </data>


   <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".view.fragment.MessagesFragment">



                 <android.support.v7.widget.RecyclerView
                    android:id="@+id/rv_message"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_margin="5dp"
                    android:background="#ffffff"
                    android:paddingLeft="4dp"
                    android:paddingRight="4dp"
                    android:layout_marginTop="0dp"
                    android:layout_below="@+id/kjk"
                    android:layout_above="@+id/rv_message_container"
                    tools:listitem="@layout/test"
                    />



            </RelativeLayout>


</layout>

Vertical Recyclerview子布局

    <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <import
            alias="cons"
            type="com.sukshi.sukshichat.utils.ConstantsFirebase"/>

        <import type="android.view.View"/>

        <variable
            name="messageViewModel"
            type="com.sukshi.sukshichat.viewmodel.MessageAdapterViewModel"/>
    </data>
    <android.support.percent.PercentRelativeLayout

        android:layout_height="wrap_content"
        android:id="@+id/rv_container"
        android:layout_width="wrap_content">


        <android.support.v7.widget.RecyclerView
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginTop="10dp"
            android:id="@+id/nested_recyclerview"
            >





        </android.support.v7.widget.RecyclerView>

        <RelativeLayout
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="4dp"
            android:id="@+id/sender"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="4dp"
            app:layout_widthPercent="70%">
            <hani.momanii.supernova_emoji_library.Helper.EmojiconTextView
                android:layout_height="wrap_content"
                android:id="@+id/tv_item_message"
                android:layout_width="wrap_content"
                android:maxWidth="300dp"
                android:textColor="#ffffff"
                android:text="@{messageViewModel.message}"
                android:background="@drawable/chat_sender"
              android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
                android:padding="10dp" />




            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{messageViewModel.time}"
                android:layout_marginRight="4dp"
                android:id="@+id/tv_item_message_time"
                android:layout_alignBottom="@+id/tv_item_message"
                android:layout_toLeftOf="@+id/tv_item_message"/>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <ImageView
                    android:id="@+id/iv_image"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:adjustViewBounds="true"
                    android:maxHeight="@dimen/item_message_max_height"
                    android:maxWidth="@dimen/item_message_max_width"
                    android:onClick="@{messageViewModel::onItemClick}"
                    android:scaleType="centerCrop"
                    android:transitionName="shared"
                    android:visibility="@{messageViewModel.typeMessage ? View.GONE : View.VISIBLE}"
                    app:mapLocation="@{messageViewModel.mapLocation}"
                    app:photoUrlMessage="@{messageViewModel.message}"/>
            </FrameLayout>


        </RelativeLayout>
        <RelativeLayout
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="4dp"
            android:id="@+id/reciever"
            android:layout_marginBottom="4dp"
            app:layout_widthPercent="70%">



            <hani.momanii.supernova_emoji_library.Helper.EmojiconTextView
                android:layout_height="wrap_content"
                android:id="@+id/tv_item_message1"
                android:layout_width="wrap_content"
                android:background="@drawable/chat_recieve"
                android:maxWidth="300dp"
                android:textColor="#000000"
                android:text="@{messageViewModel.message}"
                android:padding="10dp" />

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/show_garments2"
                android:text="Show Garments"
                android:visibility="gone"
                android:background="@drawable/chat_recieve"
                android:elevation="10dp"
android:paddingLeft="10dp"
                android:textColor="#000000"
                style="@style/Widget.AppCompat.Button.Colored"
                android:layout_alignParentTop="true"
               android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"

                />



            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{messageViewModel.time}"
                android:id="@+id/tv_item_message_time11"
                android:layout_marginLeft="4dp"
                android:layout_alignBottom="@+id/tv_item_message1"
                android:layout_toRightOf="@+id/tv_item_message1"/>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <ImageView
                    android:id="@+id/iv_image1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:adjustViewBounds="true"
                    android:maxHeight="@dimen/item_message_max_height"
                    android:maxWidth="@dimen/item_message_max_width"
                    android:onClick="@{messageViewModel::onItemClick}"
                    android:scaleType="centerCrop"
                    android:transitionName="shared"
                    android:visibility="@{messageViewModel.typeMessage ? View.GONE : View.VISIBLE}"
                    app:mapLocation="@{messageViewModel.mapLocation}"
                    app:photoUrlMessage="@{messageViewModel.message}"/>
            </FrameLayout>


        </RelativeLayout>





    </android.support.percent.PercentRelativeLayout>
</layout>

Vertical Recyclerview适配器

    private void initializeFirebase() {
        if (valueUserListener == null) {
            valueUserListener = createFirebaseUsersListeners();
        }
        mRefUsers = FirebaseDatabase.getInstance().getReference(ConstantsFirebase.FIREBASE_LOCATION_USERS);
        mRefUsers.keepSynced(true);
        mRefUsers.addValueEventListener(valueUserListener);

        Query messagesRef = FirebaseDatabase.getInstance()
                .getReference(ConstantsFirebase.FIREBASE_LOCATION_CHAT)
                .child(mChildChatKey)
                .orderByKey().limitToLast(50);
        messagesRef.keepSynced(true);
        attachMessagesToRecyclerView(messagesRef);
    }
    private void attachMessagesToRecyclerView(final Query messagesReference) {
        mAdapter = new FirebaseRecyclerAdapter<Message, MessageItemHolder>(Message.class,
                R.layout.test123, MessageItemHolder.class, messagesReference) {
            @Override
            public MessageItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                Test123Binding adapterItemMessageBinding = DataBindingUtil.inflate(LayoutInflater
                        .from(parent.getContext()), viewType, parent, false);
                return new MessageItemHolder(adapterItemMessageBinding);
            }

            @Override
            protected void populateViewHolder(final MessageItemHolder viewHolder, final Message message, int position) {
                int index = mUsersEmails.indexOf(message.getEmail());
                if (index != -1) {

                    viewHolder.bindMessage(mUsers.get(index), message, MessagesFragment.this);

                }

                if (viewHolder.mAdapterItemMessageBinding.getMessageViewModel().isSender()){

                    viewHolder.mAdapterItemMessageBinding.reciever.setVisibility(View.GONE);
                    viewHolder.mAdapterItemMessageBinding.sender.setVisibility(View.VISIBLE);

                }else {

                    viewHolder.mAdapterItemMessageBinding.reciever.setVisibility(View.VISIBLE);
                    viewHolder.mAdapterItemMessageBinding.sender.setVisibility(View.GONE);

                }
                String http = message.getMessage();

              //  if (htttpmessage != null){

                    if (http.contains("google") && message.getType() == 0){

                    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
                            RelativeLayout.LayoutParams.WRAP_CONTENT);
                    viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setLayoutParams(params);
                        filterLink = message.getMessage();
                        ListOfdataAdapter.clear();
                        JSON_HTTP_CALL(filterLink);
                        nestedRecyclerview(viewHolder);
                        viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setVisibility(View.VISIBLE);

                        viewHolder.mAdapterItemMessageBinding.tvItemMessage1.setVisibility(View.INVISIBLE);

                    //  filterLink = message.getFilterLink();

                }else{

                   RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(0,
                            0);
                    viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setLayoutParams(params);

                    viewHolder.bindMessage(mUsers.get(index), message, MessagesFragment.this);
                    viewHolder.mAdapterItemMessageBinding.tvItemMessage1.setVisibility(View.VISIBLE);


                }

                if (message.getType() == 1 || message.getType() == 2){

                        viewHolder.mAdapterItemMessageBinding.tvItemMessage.setVisibility(View.INVISIBLE);

                }else {

                    viewHolder.mAdapterItemMessageBinding.tvItemMessage.setVisibility(View.VISIBLE);

                }


             /* viewHolder.mAdapterItemMessageBinding.showGarments2.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        showpDialog();

                        filterLink = message.getMessage();

                        ListOfdataAdapter.clear();



                        JSON_HTTP_CALL(filterLink);



                    }
                });



*/
            }





        };


        mFragmentMessagesBinding.rvMessage.setAdapter(mAdapter);
        mFragmentMessagesBinding.rvMessage.getAdapter().registerAdapterDataObserver(
                new RecyclerView.AdapterDataObserver() {
                    @Override public void onItemRangeInserted(int position, int itemCount) {
                        super.onItemRangeInserted(position, itemCount);
                        mFragmentMessagesBinding.rvMessage.scrollToPosition(position);
                    }
                });
    }

因此,只要下面的消息键中有URl,就会调用方法

  public void JSON_HTTP_CALL(String url){

    RequestOfJSonArray = new JsonArrayRequest(url,

            new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {

                    ParseJSonResponse(response);
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {





                }
            });

    requestQueue = Volley.newRequestQueue(getActivity());

    requestQueue.add(RequestOfJSonArray);
}

public void ParseJSonResponse(JSONArray array){

    for(int i = 0; i<array.length(); i++) {

        UploadImage GetDataAdapter2 = new UploadImage();

        JSONObject json = null;
        try {

            hidepDialog();

            json = array.getJSONObject(i);

            GetDataAdapter2.setBrand_name(json.getString(Image_Name_JSON));

            // Adding image title name in array to display on RecyclerView click event.
            ImageTitleNameArrayListForClick.add(json.getString(Image_Name_JSON));

            GetDataAdapter2.setImage(json.getString(Image_URL_JSON));
            GetDataAdapter2.setGarment_price(json.getString(garment_price));
            GetDataAdapter2.setGarment_name(json.getString(garment_name));
            GetDataAdapter2.setImage_full(json.getString(image_full));
            GetDataAdapter2.setDesc_text(json.getString(desc_text));


        } catch (JSONException e) {

            e.printStackTrace();
        }
        ListOfdataAdapter.add(GetDataAdapter2);
      //  showFragment();


    }
}

Horizantal Recyclerview适配器

    final WrapContentLinearLayoutManager linearLayoutManager = new WrapContentLinearLayoutManager(getActivity());
    linearLayoutManager.setOrientation(WrapContentLinearLayoutManager.HORIZONTAL);
    viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setLayoutManager(linearLayoutManager);
    viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setHasFixedSize(true);
    //mFragmentMessagesBinding.recyclerview1.addItemDecoration(new PaddingItemDecoration(size));
    viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setItemAnimator(new DefaultItemAnimator());
    DialogRecyclerViewAdapter rvAdapter = new DialogRecyclerViewAdapter(ListOfdataAdapter, getActivity());
    viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setAdapter(rvAdapter);

    rvAdapter.notifyDataSetChanged();

Horizantal Recyclerview适配器

public class DialogRecyclerViewAdapter extends RecyclerView.Adapter<DialogRecyclerViewAdapter.ViewHolder> {

    Context context;

    List<UploadImage> dataAdapters;
    private SharedPreferences.Editor mSharedPrefEditor;

    ImageLoader imageLoader;


    public DialogRecyclerViewAdapter(List<UploadImage> getDataAdapter, Context context){

        super();
        this.dataAdapters = getDataAdapter;
        this.context = context;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);

        ViewHolder viewHolder = new ViewHolder(view);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder Viewholder, int position) {

        final UploadImage dataAdapterOBJ =  dataAdapters.get(position);

        imageLoader = ImageAdapter.getInstance(context).getImageLoader();

        imageLoader.get(dataAdapterOBJ.getImage(),
                ImageLoader.getImageListener(
                        Viewholder.VollyImageView,//Server Image
                        R.drawable.loading_1,//Before loading server image the default showing image.
                        android.R.drawable.ic_dialog_alert //Error image if requested image dose not found on server.
                )
        );

    }

    @Override
    public int getItemCount() {

        return dataAdapters.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder{

        public TextView ImageTitleTextView, garment_price, size;
        public NetworkImageView VollyImageView ;

        public ViewHolder(View itemView) {

            super(itemView);





            VollyImageView = (NetworkImageView) itemView.findViewById(R.id.VolleyImageView) ;

        }
    }
}

Vertical Recyclerview ViewHolder

 public static class MessageItemHolder extends RecyclerView.ViewHolder {
    private Test123Binding mAdapterItemMessageBinding;

    public MessageItemHolder(Test123Binding adapterItemMessageBinding) {
        super(adapterItemMessageBinding.rvContainer);
        mAdapterItemMessageBinding = adapterItemMessageBinding;

    }

    public void bindMessage(User user, Message message, MessageAdapterViewModelContract contract) {
        if (mAdapterItemMessageBinding.getMessageViewModel() == null) {
            mAdapterItemMessageBinding.setMessageViewModel(new MessageAdapterViewModel(user,
                    encodedMail, message, contract));
        } else {
            mAdapterItemMessageBinding.getMessageViewModel().setUser(user);
            mAdapterItemMessageBinding.getMessageViewModel().setMessage(message);
        }
    }
}

0 个答案:

没有答案