AppBarLayout CollapsingToolbar如何禁用EditText点击展开?

时间:2018-06-09 12:56:19

标签: android-edittext material-design android-collapsingtoolbarlayout android-appbarlayout

在我的测试应用中,我在AppBarLayout折叠时禁用了扩展(通过滚动RecycleView)。我这样做是将addOnOffsetChangedListener添加到AppBarLayout。 但是,当我点击EditText时,它会再次展开,但我不希望它展开。 单击AppBarLayout时如何禁用EditText的扩展?

我已经放了整个代码,这样每个人都可以复制/粘贴代码,创建新项目并快速测试。

以下是.gif的外观

enter image description here

这是XML代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">



        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleTextAppearance="@android:color/transparent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitXY"
                android:src="@drawable/beachcroatia"/>

        </android.support.design.widget.CollapsingToolbarLayout>


    </android.support.design.widget.AppBarLayout>



    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycleView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="?attr/actionBarSize"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />



    <LinearLayout
        android:id="@+id/messages_linear_layout"
        android:layout_width="match_parent"
        android:layout_height="58dp"
        android:layout_gravity="bottom"
        android:background="#E1F5FE"
        android:orientation="horizontal"
        tools:layout_editor_absoluteY="453dp">



        <EditText
            android:id="@+id/editText_messageBox"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_alignParentBottom="true"
            android:layout_gravity="center"
            android:layout_weight="0.85"
            android:hint="Enter a message"/>

        <ImageView
            android:id="@+id/messages_sendArrow"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_gravity="center"
            android:layout_weight="0.15"
            android:src="@drawable/ic_send_message_" />

    </LinearLayout>

</android.support.design.widget.CoordinatorLayout>

以下是完整的MainActivity代码:

&#13;
&#13;
public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerChat;
    private AdapterChat mAdapterChat;
    CollapsingToolbarLayout collapsingToolbarLayout;
    AppBarLayout appBarLayout;
    ImageView sendMessageImageViewButton;
    EditText editTextMessage;

    private List<Message> messagesList;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
        appBarLayout = findViewById(R.id.app_bar_layout);
        sendMessageImageViewButton = findViewById(R.id.messages_sendArrow);
        editTextMessage = findViewById(R.id.editText_messageBox);

        messagesList = new ArrayList<>();
        messagesList.addAll(getMessagesList());


        mRecyclerChat = findViewById(R.id.recycleView);
        LinearLayoutManager manager = new LinearLayoutManager(this);
        mRecyclerChat.setLayoutManager(manager);
        mAdapterChat = new AdapterChat(this, messagesList);
        mRecyclerChat.setAdapter(mAdapterChat);

        //move to the last item in recycleview
        mRecyclerChat.getLayoutManager().scrollToPosition(mAdapterChat.getMessagesObekt().size() - 1);

        editTextMessage.requestFocus();



        getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);


        appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if (Math.abs(verticalOffset) == appBarLayout.getTotalScrollRange()) {
                    // Collapsed
                    Toast.makeText(MainActivity.this, "Collapsed", Toast.LENGTH_SHORT).show();

                    // disable expanding
                    AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
                    params.setScrollFlags(0);

                } else if (verticalOffset == 0) {
                    Toast.makeText(MainActivity.this, "Extend", Toast.LENGTH_SHORT).show();
                    // Expanded
                } else {
                    // Somewhere in between
                }
            }
        });

       

      


        //sending new message and updating recycleview
        sendMessageImageViewButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "Message Send", Toast.LENGTH_SHORT).show();
                mAdapterChat.updateLastMessage(new Message(editTextMessage.getText().toString()));
                editTextMessage.getText().clear();
                mRecyclerChat.getLayoutManager().scrollToPosition(mAdapterChat.getMessagesObekt().size() - 1);
            }
        });
    }



    //ading some items to a list
    private List<Message> getMessagesList() {
        List<Message> mMessages = new ArrayList<>();

        for (int i = 0; i < 200; i++) {
            mMessages.add(new Message("message " + i));
        }

        return mMessages;
    }
}
&#13;
&#13;
&#13;

这是我的消息类,我在其中添加要在RecycleView中显示的虚拟数据

&#13;
&#13;
public class Message {
    private String message;

    public Message(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
&#13;
&#13;
&#13;

这是RecycleView适配器代码:

&#13;
&#13;
package com.example.petar.collapsingtolbartestiramo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class AdapterChat extends RecyclerView.Adapter<AdapterChat.ChatHolder> {
    private LayoutInflater mInflater;
    private List<Message> messagesObekt;

    public AdapterChat(Context context, List<Message> listOfMassages) {
        mInflater = LayoutInflater.from(context);
        messagesObekt = new ArrayList<>();
        messagesObekt.addAll(listOfMassages);
        notifyDataSetChanged();
    }

    public void updateChat(List<Message> porukeObjekt){
        this.messagesObekt.addAll(porukeObjekt);
        notifyDataSetChanged();
    }
    public void updateLastMessage(Message porukeObjekt) {
        this.messagesObekt.add(porukeObjekt);
        //notifyDataSetChanged();
        notifyItemInserted(messagesObekt.size());
    }

    public List<Message> getMessagesObekt() {
        return messagesObekt;
    }

    @Override
    public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.list_message, parent, false);
        ChatHolder holder = new ChatHolder(view, messagesObekt);
        return holder;
    }

    @Override
    public void onBindViewHolder(ChatHolder holder, int position) {
        holder.textViewMessage.setText(messagesObekt.get(position).getMessage());
    }

    @Override
    public int getItemCount() {
        return messagesObekt.size();
    }



    public static class ChatHolder extends RecyclerView.ViewHolder {

        TextView textViewMessage;

        public ChatHolder(View itemView, List<Message> messagesObekt) {
            super(itemView);

            textViewMessage = itemView.findViewById(R.id.rv_message);
        }
    }
}
&#13;
&#13;
&#13;

这是RecycleView项目XML代码(list_message.xml)

&#13;
&#13;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="5dp"
    android:orientation="vertical">
    <TextView
        android:id="@+id/rv_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Poruka Ovdje"
        android:textSize="14sp"/>

</LinearLayout>
&#13;
&#13;
&#13;

修改

我尝试将焦点监听器添加到EditText但是,这没有帮助。这是我尝试的方式:

     editTextMessage.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if(hasFocus){
                    appBarLayout.setExpanded(false);
                    AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
                    params.setScrollFlags(0);
                }
            }
        });

2 个答案:

答案 0 :(得分:1)

<块引用>

我不知道是最好的解决方案,但效果很好。如果有人有更好的解决方案,请随时写出来。

确实有更好、更简洁、更简单的解决方案。 导致此“问题”的罪魁祸首实际上是 Google 在 AppBarLayout.ScrollingViewBehavior 中添加的一项功能。这是您通过 app:layout_behavior="@string/appbar_scrolling_view_behavior" 设置的。在该类中,只要显示键盘,onRequestChildRectangleOnScreen 就会调用 setExpanded(false, !immediate)。您只需覆盖此方法并返回 false 以禁用此默认行为。将此类添加到您的项目中:

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import com.google.android.material.appbar.AppBarLayout;

public class FixedScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior {

    public FixedScrollingViewBehavior() {
        super();
    }

    public FixedScrollingViewBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onRequestChildRectangleOnScreen(@NonNull CoordinatorLayout parent,
            @NonNull View child, @NonNull Rect rectangle, boolean immediate) {
        return false;
    }
}

然后通过将 app:layout_behavior="@string/appbar_scrolling_view_behavior" 更改为 app:layout_behavior="your.source.package.FixedScrollingViewBehavior" 来使用这个新类。

答案 1 :(得分:0)

我找到了答案。我不知道是最好的解决方案,但效果很好。如果有人有更好的解决方案,请随时写下来。

所以,我做的是当我点击AppBarLayoutEditText获得焦点时,我将整个EditText参数设为0。 因此,当点击EditText时,AppBarLayout仍然存在,但现在他的身高为0并且不可见。

这就是诀窍:

&#13;
&#13;
 //Collaps AppBarLayout
    public void collapsAppBarLayout(){
        CoordinatorLayout.LayoutParams params =(CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
        params.height = 0; // setting new param height to 0
        //setting params to appbarLayout (now AppBarLayout is 0)
        appBarLayout.setLayoutParams(params);
        appBarLayout.setExpanded(false);
    }
&#13;
&#13;
&#13;

另外,如果你想要扩展选项,你需要保存以前参数的高度,然后再添加那个高度。

所以,这是我如何做到的代码: 拳头,当我滚动RecycleView时,我使用appBarLayout禁用展开addOnOffsetChangedListener。然而,我也保留了参数高度以备将来使用。

&#13;
&#13;
int sizeParams; //save params height 


appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if (Math.abs(verticalOffset) == appBarLayout.getTotalScrollRange()) {
                    // Collapsed
                    Toast.makeText(MainActivity.this, "Collapsed", Toast.LENGTH_SHORT).show();
                    // disable expanding and scroll
                    AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
                    params.setScrollFlags(0);
                    //saving height for future use
                    sizeParams =  params.height;
                } else if (verticalOffset == 0) {
                    Toast.makeText(MainActivity.this, "Extend", Toast.LENGTH_SHORT).show();
                    // Expanded
                } else {
                    // Somewhere in between
                }
            }
        });
&#13;
&#13;
&#13;

现在我制作了这个我需要展开/折叠时调用的方法。

&#13;
&#13;
   //Collaps AppBarLayout
    public void collapsAppBarLayout(){
        CoordinatorLayout.LayoutParams params =(CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
        sizeParams =  params.height;//save params height for future use
        params.height = 0; // setting new param height to 0
        //setting params to appbarLayout (now AppBarLayout is 0
        appBarLayout.setLayoutParams(params);
        appBarLayout.setExpanded(false);
    }
    //Expand AppBarLayout
    public void expandAppBarLayout(){
        CoordinatorLayout.LayoutParams params =(CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
        params.height = 3*sizeParams; // HEIGHT
        appBarLayout.setLayoutParams(params); //add height to appbarlayout
        //enable scroll and expand 
        AppBarLayout.LayoutParams params1 = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
        params1.setScrollFlags(1);
        appBarLayout.setExpanded(true);//expand
    }
&#13;
&#13;
&#13;