【问题标题】:Layout problems when opening the keyboard on android在android上打开键盘时的布局问题
【发布时间】:2020-08-26 22:53:10
【问题描述】:

我在 Android 上的聊天活动布局有问题。我在一个简单的应用程序中进行测试,以便您更容易理解。

这是 xml 布局:

<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:id="@+id/constraintMessage"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/wallpaper">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        ads:layout_constraintBottom_toBottomOf="parent"
        ads:layout_constraintEnd_toEndOf="parent"
        ads:layout_constraintStart_toStartOf="parent"
        ads:layout_constraintTop_toTopOf="parent">

        <ListView
            android:id="@+id/listViewMessages"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:paddingTop="7dp" />

        <LinearLayout
            android:id="@+id/linearLayoutCaixaTexto"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="5dp"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="8dp"
            android:layout_weight="0"
            android:background="@drawable/fundo_mensagem_chat_branco"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingLeft="16dp">

            <EditText
                android:id="@+id/editMessage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#00000000"
                android:cursorVisible="true"
                android:ems="10"
                android:hint="Type here..."
                android:imeOptions="actionDone"
                android:inputType="textPersonName"
                android:linksClickable="true"
                android:longClickable="true"
                android:maxLength="500"
                android:paddingRight="5dp"
                android:singleLine="true"
                android:soundEffectsEnabled="false"
                android:textColor="@android:color/black"
                android:textStyle="normal" />

            <ImageView
                android:id="@+id/imageViewSendMessage"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_marginTop="8dp"
                android:layout_marginEnd="16dp"
                android:layout_marginRight="16dp"
                android:layout_marginBottom="8dp"
                ads:srcCompat="@drawable/ic_enviar_preto_24dp" />

        </LinearLayout>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

这些都是关于键盘的问题:

  1. 当您单击 EditText 时,键盘会正常快速打开。但是,当我将项目添加到 listView(使其填满整个屏幕)时,当单击 EditText 时,键盘需要一段时间才能打开,也需要一段时间才能隐藏,它有点卡住了。这是一个非常烦人的问题。

  2. 当键盘打开时,ConstraintLayout 中的背景发生了变化,您可以在下图中看到不同之处。当我们放置对话的背景图像时,我希望键盘位于背景之上,就像聊天应用程序一样。我得到的最接近的是将“adjustNothing”放在 windowSoftInputMode 中,但随后键盘在 EditText 和 ListView 上。

看,如果我在 windowSoftInputMode 中使用“adjustPan”,就会发生这种情况:

简而言之,我希望它看起来像这样:

  • 键盘应该可以快速打开和隐藏。
  • EditText 必须始终位于键盘上方(这已经发生了)。
  • 打开键盘时不应更改对话的背景图像。

我录制了一个简短的视频,以便您查看问题。注意视频中listView中没有消息的时候,键盘开合快,有消息的时候就慢,卡住。还要注意背景,当你打开键盘时它会改变。在视频的最后我在另一个应用中记录了同样的情况,你可以看到键盘正常打开,壁纸没有改变。

视频:https://www.youtube.com/watch?v=DdMFufZ_Glg&feature=youtu.be

其他代码(如果需要):

AndroidManifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.applicationtest">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:label="Chat"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="adjustResize|stateHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

主活动:

public class MainActivity extends AppCompatActivity {
    
    private List<Message> listMessages = new ArrayList<>();
    private EditText editMessage;
    private ImageView imageViewSendMessage;
    private MessageAdapter adapterMessages;
    private ListView listViewMessages;

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

        editMessage = findViewById(R.id.editMessage);
        imageViewSendMessage = findViewById(R.id.imageViewSendMessage);
        listViewMessages = findViewById(R.id.listViewMessages);

        adapterMessages = new MessageAdapter(listMessages, this);
        listViewMessages.setDividerHeight(0);
        listViewMessages.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
        listViewMessages.setAdapter(adapterMessages);

        imageViewSendMessage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!editMessage.getText().toString().isEmpty()) {

                    Message message = new Message();
                    message.setM(editMessage.getText().toString());
                    message.setDm("20/08/2022");
                    listMessages.add(message);
                    adapterMessages.notifyDataSetChanged();

                }
            }
        });

    }
}

适配器类:

public class MessageAdapter extends ArrayAdapter<Message> {

    private Context context;
    private List<Message> mensagens;

    public MessageAdapter(List<Message> list, Context c) {
        super(c, 0, list);
        this.context = c;
        this.mensagens = list;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View listItem = convertView;

        Message message = mensagens.get(position);

        listItem = LayoutInflater.from(context).inflate(R.layout.adapter_msg_rement,parent,false);

        TextView textMensagem;
        TextView dataMensagem;

        textMensagem = listItem.findViewById(R.id.textMensagemTexto);
        dataMensagem = listItem.findViewById(R.id.dataMensagem);

        textMensagem.setText(message.getM());
        dataMensagem.setText(message.getDm());
        textMensagem.setTextColor(Color.parseColor("#000000"));

        return listItem;
    }

}

【问题讨论】:

    标签: android


    【解决方案1】:

    ListView 尝试重用视图对象以提高性能并避免响应用户滚动时出现延迟。要利用此功能,请在创建或扩充新视图对象之前检查提供给 getView(...) 的 convertView 是否为空。有关确保流畅用户体验的更多方法,请参阅使 ListView 滚动平滑。

    如上所述,您应该使用convertView 来处理性能 我猜这就是导致您的“小卡顿”问题的原因。

    正如我所说,我建议使用RecyclerView

    关于背景图片 - 您可以使用 adjustPan 将整个布局推到上面并避免调整图片大小(希望这是您想要的...)

    祝你好运

    【讨论】:

    • 您好,谢谢您的回复。我将更多地研究convertView,看看我能不能得到一些东西。关于背景,我已经尝试使用 AdjustPan 并且它不起作用。我用结果的屏幕截图编辑了问题。
    • @jvoaojvictor 没问题,只需点击上面的链接即可。对于背景问题,试试这个answer,如果它可以帮助你知道该怎么做:)
    猜你喜欢
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多