#java #android #android-layout
#java #Android #android-layout
Вопрос:
Я пытаюсь заставить приложение работать, но когда я объявляю одну кнопку в макете, отображаются две кнопки. Они отображаются в textviews и отображаются в правом верхнем углу. Есть две кнопки, и я хочу, чтобы одна кнопка находилась внизу страницы.
Вот файл макета:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:id="@ id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.useprovider.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="listContacts"/>
<TextView
android:text="TextView"
android:layout_width="0dp"
android:layout_height="60dp"
android:id="@ id/contactName"
app:layout_constraintLeft_toLeftOf="@ id/activity_main"
android:layout_marginStart="63dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintRight_toRightOf="@ id/activity_main"
android:layout_marginEnd="63dp"
tools:layout_constraintRight_creator="1"
app:layout_constraintBottom_toTopOf="@ id/contactID"
android:layout_marginBottom="40dp"
tools:layout_constraintBottom_creator="1" />
<TextView
android:text="TextView"
android:layout_width="0dp"
android:layout_height="64dp"
android:id="@ id/contactID"
app:layout_constraintLeft_toLeftOf="@ id/activity_main"
android:layout_marginStart="63dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintRight_toRightOf="@ id/activity_main"
android:layout_marginEnd="63dp"
tools:layout_constraintRight_creator="1"
app:layout_constraintBottom_toBottomOf="@ id/activity_main"
android:layout_marginBottom="56dp"
tools:layout_constraintBottom_creator="1" />
<ListView
android:layout_height="0dp"
android:id="@android:id/list"
android:layout_width="wrap_content"
app:layout_constraintLeft_toLeftOf="@ id/activity_main"
app:layout_constraintTop_toTopOf="@ id/activity_main"
tools:layout_constraintTop_creator="1"
app:layout_constraintRight_toRightOf="@ id/activity_main"
app:layout_constraintBottom_toTopOf="@ id/contactName"
android:layout_marginBottom="5dp"
tools:layout_constraintBottom_creator="1" />
</android.support.constraint.ConstraintLayout>
и вот класс java, который соответствует файлу макета:
package com.example.useprovider;
import android.content.Intent;
import android.os.Bundle;
import android.Manifest;
import android.app.ListActivity;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.CursorLoader;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends ListActivity {
final private int REQUEST_READ_CONTACTS = 123;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS},
REQUEST_READ_CONTACTS);
} else{
ListContacts();
}
}
@Override
public void onRequestPermissionsResult(int requestCode
, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_READ_CONTACTS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
ListContacts();
} else {
Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
protected void ListContacts(){
Uri allContacts = Uri.parse("content://contacts/people");
Cursor c;
CursorLoader cursorLoader = new CursorLoader(this, allContacts, null, null, null, null);
c = cursorLoader.loadInBackground();
int numberofrecords = c.getCount();
System.out.println("number of contacts returned: " numberofrecords);
String[] columns = new String[]{
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts._ID};
int[] views = new int[]{R.id.contactName, R.id.contactID};
SimpleCursorAdapter adapter;
adapter = new SimpleCursorAdapter(
this, R.layout.activity_main, c, columns, views,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
this.setListAdapter(adapter);
}
public void listContacts(View view){
Intent intent = new Intent(this, ContactList.class);
startActivity(intent);
}
}
Комментарии:
1. Кнопка, видимая в файле макета, должна быть ограничена представлением или его родительским элементом, иначе она застряла в углу. Установите ограничения для кнопки, а затем посмотрите, есть ли еще две.
2. @KesWalker приведите несколько примеров ограничений, которые были бы необходимы?
3. Теперь я получаю ноль кнопок после применения app: layout_constraintBottom_toTopOf=»@android: id / список» app: layout_constraintleft_tolefto=»@ id / ContactName»/>
4. @hippoman можете ли вы перейти в режим разработки макета, чтобы лучше понять, как все расположено?
5. вы гений в этом предложении, но на нем все еще отображаются 2 кнопки, по одной для каждого элемента listview, в то время как в режиме разработки отображается одна кнопка на первом элементе listview. После перетаскивания кнопки в нижний левый угол она устанавливает абсолютные координаты x и абсолютные координаты y, но по-прежнему отображает 2 кнопки в тех же положениях, что и раньше.
Ответ №1:
SimpleCursorAdapter adapter;
adapter = new SimpleCursorAdapter(
this, R.layout.activity_main, c, columns, views,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
Вы определили макет вашего основного действия как макет, который адаптер курсора будет использовать для создания внешнего вида каждого элемента в списке. https://developer.android.com/reference/android/widget/SimpleCursorAdapter.html#SimpleCursorAdapter(android.content.Контекст, int, android.database.Курсор, java.lang.Строка[], int[], int)
Результат: кнопка, а также текстовые представления будут реплицированы для каждого элемента в виде списка. Ваша проблема не так проста, как просто наличие двух кнопок. Для каждого вашего контакта будут созданы кнопка, представление списка и 2 текстовых представления, тогда как вам нужно всего 2 текстовых представления для каждого контакта.
Простое решение: создайте новый XML-файл, содержащий только текстовые представления, необходимые для отображения имени контакта и идентификатора, и предоставьте его адаптеру в качестве макета.
Макет элемента списка:
//list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
tools:context=".Debug1ListItem">
<TextView
android:id="@ id/contactName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@ id/contactID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/contactName" />
</android.support.constraint.ConstraintLayout>
Конструкция адаптера:
SimpleCursorAdapter adapter;
adapter = new SimpleCursorAdapter(
this, R.layout.list_item, c, columns, views,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);