Подскажите библиотеку для табличного отображения данных, максимально по виду и функционалу
приближенную к DBGrid из Delphi или Майкрософтовским DataGrid.
Ответы
Ответ 1
используйте TableLayout
вот пример
activity_main.xml
управлять таблицой (MainActivity.java)
package com.pavan.sqlitetabledemo;
import android.app.Activity;
import android.app.ProgressDialog;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TableRow.LayoutParams;
import android.widget.TextView;
public class MainActivity extends Activity {
TableLayout table_layout;
EditText firstname_et, lastname_et;
Button addmem_btn;
SQLController sqlcon;
ProgressDialog PD;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sqlcon = new SQLController(this);
firstname_et = (EditText) findViewById(R.id.fistname_et_id);
lastname_et = (EditText) findViewById(R.id.lastname_et_id);
addmem_btn = (Button) findViewById(R.id.addmem_btn_id);
table_layout = (TableLayout) findViewById(R.id.tableLayout1);
BuildTable();
addmem_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new MyAsync().execute();
}
});
}
private void BuildTable() {
sqlcon.open();
Cursor c = sqlcon.readEntry();
int rows = c.getCount();
int cols = c.getColumnCount();
c.moveToFirst();
// outer for loop
for (int i = 0; i < rows; i++) {
TableRow row = new TableRow(this);
row.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
// inner for loop
for (int j = 0; j < cols; j++) {
TextView tv = new TextView(this);
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
tv.setBackgroundResource(R.drawable.cell_shape);
tv.setGravity(Gravity.CENTER);
tv.setTextSize(18);
tv.setPadding(0, 5, 0, 5);
tv.setText(c.getString(j));
row.addView(tv);
}
c.moveToNext();
table_layout.addView(row);
}
sqlcon.close();
}
private class MyAsync extends AsyncTask {
@Override
protected void onPreExecute() {
super.onPreExecute();
table_layout.removeAllViews();
PD = new ProgressDialog(MainActivity.this);
PD.setTitle("Please Wait..");
PD.setMessage("Loading...");
PD.setCancelable(false);
PD.show();
}
@Override
protected Void doInBackground(Void... params) {
String firstname = firstname_et.getText().toString();
String lastname = lastname_et.getText().toString();
// inserting data
sqlcon.open();
sqlcon.insertData(firstname, lastname);
// BuildTable();
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
BuildTable();
PD.dismiss();
}
}
}
Полный код тут
исходники тут SQLiteTableDemo.zip
Как я понимаю есть два пути сделать поддержку mdpi-hdpi-xhdpi-xxhdpi экранов:
Делать под каждую плотность свой layout, со своими размерами и
ложить его в соответствующую папку(layout-xhdpi etc)
Сделать один layout и сделать под каждую плотность свои
values/dimens.xml
В первом случае будет браться шаблон более менее подходящий под текущий экран, а
во втором будут браться значения размеров под соответствующий экран.
Какой из этих способов лучше ?
Если я что-то не так понял - поправте. Спасибо.
Ответы
Ответ 1
Все правильно понял. Только есть третий, идеальный вариант - делать резиновую разметку,
которая будет выглядеть одинаково на всех экранах. Вес элемента в помощь. Разные layout`ы
можно под планшет/телефон делать, но не под каждую плотность
Видел как некоторые разработчики удаляют эти строки из layout файла, хотя они появляются
изначально по умолчанию. Так что, стоит ли удалять их, раз они не выпоняют важной роли
в проекте ?
Ответы
Ответ 1
xmlns:app нужен для обозначения кастомных свойст View. xmlns:tools - позволяет среде
разработки (в нашем случае, Android Studio) правильно отобразить компоненты для просмотра
в режиме дизайна.
Подробнее про tools
Подробнее про app
Такая проблема. Создаем приложение для зоопарка устройств. и необходимо чтобы дизайн
совпадал пиксель в пиксель. Впринципе все смогли разрулить с помощью dpi, выставляя
значения в них. на разных екранах делаем скрин, вставляем в фотошоп и все накладывается
пиксель в пиксель. Но есть такие телефоны типо нексуса 6, у которых нет конкретного
размера в dpi тоесть он между xxhdpi и xxxhdpi. И соотвественно когда я указываю
размер кнопки например 50dpi то она выглядит иначе чем я ожидаю. Я не знаю как это
решить. Из этого вопросы
Как это решается?
Как сделать чтобы на определенном телефоне поставлялся определенный лейаут?
НАШЕЛ
res/layout-sw600dp/main_activity.xml # For 7” tablets (600dp wide and bigger)
res/layout-sw720dp/main_activity.xml # For 10” tablets (720dp wide and bigger)
смущает 600dp wide and bigger это что этот лейаут будет и для экранов с большей плотностью
тоже? а как сделать только для конкретного экрана?
Ответы
Ответ 1
Можно например так:
if(android.os.Build.MODEL.contains("Nexus 6"))
setContentView(R.layout.my_layout_for_nexus_6);
Мне и самому то не нравится такое выделывать, но что делать раз Nexus такой специфичный :)
Ответ 2
Кроме всего ранее озвученного можно попробовать вынести размеры елементов и шрифтов
в dimens. Причем раскидать их по папкам с комбинацией денсити и размера:
values-sw320dp-xhdpi
values-sw600dp-xhdpi
values-sw720dp-xhdpi
values-sw320dp-xxhdpi
values-sw600dp-xxhdpi
values-sw720dp-xxhdpi
values-sw320dp-xxxhdpi
values-sw600dp-xxxhdpi
values-sw720dp-xxxhdpi
см. также http://developer.android.com/guide/topics/resources/providing-resources.html
Ответ 3
Nexus 6 - 730 x 410 dp
Nexus 9 - 1024 x 768 dp
Если используются разные layout'ы для портретной и альбомной ориентации (как часто
бывает), то можно учесть это:
In order to take advantage of the screen real estate on the Nexus 6
and Nexus 9, we emphasize the importance of responsive design. In the
past, if you assumed that landscape mode is significantly wider than
portrait mode, you may run into problems on a device like the Nexus 9,
which has an aspect ratio of 4:3. Instead of declaring layouts using
the layout-land or layout-port resource folder qualifiers, we strongly
recommend switching to the wdp width resource folder qualifier so
that content is laid out based on available screen width.
Тогда для Nexus 6 получаем layout-w410dp-h730dp (портретная) и layout-w730dp-h410dp
(альбомная)
На первом скриншоте - то что я вижу в android studio. На втором - то что появляется
при запуске программы. Текст находится в layout-е фрагмента.
Как избавиться от белой рамки как на втором скрине? Layout имеет свойства match_parent.
Заранее спасибо.
Ответы
Ответ 1
Никогда не пользуйтесь предпросмоторщиком, встроенным в IDE - он полон багов и править
их, скорее всего, никогда не будут, ибо им никто не пользуется, ибо он не нужен.
Отступы, кои вы видите, где-то у вас в разметке. Ищите в коде/разметке активити/фрагмента
margin и/или padding. Уберите их и отступы пропадут.
Делаю первое приложение. Мне нужно, чтобы два таймера снизу - всегда находились в
серединах двух половинок (по горизонтали). Иначе говоря, будто они в серединах двух
столбцов таблицы. А черточки должны начинаться снизу, как на картинке.
Пока работал только с ConstraintLayout, и уже замучился. У него привязка идет к краю
элемента. Т.е. если размер элемента меняется, то все двигается, да и он сам не остается
на месте. А у меня, например 01 час меняется на 1.
В сторону чего мне смотреть?
Ответы
Ответ 1
Для верстки такого макета на понадобятся опорные линии (guidline).
На макет размещаем три опорных линии (правый клик на визуальном редакторе разметки:
Helpers -> Add vertical\horizontal guidelines): две вертикальных (1 и 2) и одну горизонтальную
(3). Вертикальные делят экран на 3 равные части (33% и 66%), горизонтальная - верхнюю
четверть (25%). Чтобы изменить позицию опорной линии на проценты нужно щелкать на кружок.
Теперь закрепляем виджеты. Левые счетчики крепим правым краем к первой опорной линии,левым
краем к краю экрана (чтобы можно было провести черту до конца экрана). При этом верхний
низом к 3 опорной линии, а нижний верхом к ней же. Этим виджетам ставим атрибут android:gravity="right",
чтобы текст начинался от правого края.
Правый счетчик крепим левой стороной ко второй опорной линии, правой стороной к краю
экрана, а верхом и низом к верху и низу левого нижнего счетчика - так они будут располагаться
на одном уровне по горизонтали.
Кнопку и текст равномерно распределяем на оставшееся пространство по вертикали через
инструмент chains (правая кнопка мыши: Center -> Center Verticaly).
Линии под счетчиками можно сделать, просто указав этим виджетам в качестве фона изображение
9-path с чертой снизу - это самый простой вариант (в примере я делать этого не буду).
Вот что в итоге получилось:
Разметка:
В моей программе мне нужно использовать TextView внутри Cardview из библиотеки поддержки.
Нужны скругленные углы. Нужно иметь возможность изменять цвет элемента программно.
Следующий код:
приводит к такому результату:
Эти странные полосы и черточки меня совершенно не устраивают.
Следующий же код:
приводит к другому результату:
Второй результат мне не подходит из-за белых краев.
Третья моя попытка:
Создала файл rownded_corners.xml в папке drawable:
и в разметке второй попытки задала его в качестве фона TextView:
android:background="@drawable/rounded_corner"
Вот что получилось:
Здесь меня не устраивает белая рамка.
В общем, вопрос:
Как мне добиться однородного цвета, заполняющего весь CardView, и сохранить возможность
программно установить другой цвет.
UPDATE. Описанное в вопросе недоразумение уже разрешилось. См. мой ответ.
Ответы
Ответ 1
Попробуйте так:
card_view:cardBackgroundColor="@android:color/white"
или так:
cardView.setCardBackgroundColor(Color.WHITE);
Ответ 2
Представляете, описанное в вопросе недоразумение было вызвано тем, что используемый
мною цвет (colorPrimary) был полупрозрачным (что-то вроде #a03F51B5) и через него была
видна "кухня" построения CardView. Я изменила его на #3F51B5 и первый вариант дал
желаемый результат даже без атрибута, предложенного @ЮрийСПб.
Ответ 3
Попробуйте добавить вот этот атрибут в разметку карточки:
card_view:cardUseCompatPadding="true"
Знакомьтесь: это мой Switch!
Вот его XML код:
Я хочу перекрасить его из нежного розового цвета в зелёный. Мне кажется, что так
будет красивее. Перерыл много ресурсов в Интернете, но не нашёл ничего полезного.
Подскажите, как это сделать?
Ответы
Ответ 1
Сам по себе Switch подчиняется лишь теме Material Design, предусмотренной разработчиком.
Поэтому Google сделал элемент под названием SwitchCombat, который охотнее подчиняется
требованиям.
Вот как он создается в XML-файле активности:
...
...
Чтобы задать стиль для SwitchCombat, надо, во-первых, создать файл styles.xml и поместить
в него строки вида:
И, во-вторых, в самом SwitchCombat прописать ссылку на стиль:
Также можно изменить стиль для активного/неактивного состояния, цвет полосы передвижения
и т. д. Подробнее можно почитать здесь.
P. S. По просьбе ТС добавляю изменение цвета самого ползунка:
Здравствуйте! Как изменить размер ImageButton и при этом сохранить целую картинку,
помещенную в эту кнопку? Поместил imagebutton на экран, добавил туда картинку размером
125*125 пикселей но кнопка стала занимать пол экрана. Тут же сжать ее нельзя, а в .xml
коде стоят эти параметры:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Как можно решить эту проблему сохранив целую картинку? Пробовал заменять параметры
на 125px или 125dp, но картинка срезалась.
Ответы
Ответ 1
Установите для кнопки необходимые размеры и задайте android:scaleType="fitXY"
Ну и если необходимо, ужмите картинку.
Ответ 2
А если что-нибудь из этого попробовать?
Ответ 3
Если кнопка квадратная и её размер необходимо изменять в зависимости от устройства
android:scaleType="fitCenter"
Вписать изображение кнопки в начале
android:scaleType="fitStart"
Вписать изображение кнопки в конце
android:scaleType="fitEnd"
Имеется xml разметка для экрана.
Но если TextView будет содержать много текста, то кнопки пропадают. Текст при этом
прокручивается.
Как сделать, чтобы кнопки не исчезали?
Ответы
Ответ 1
Чтобы прокручивать TextView не обязательно помещать его внутрь ScrollView, TextView
умеет сам прокручиваться. Нужно изменить разметку TextView, добавив атрибут
android:scrollbars = "vertical"
и изменить код активности, задав метод прокрутки
import android.text.method.ScrollingMovementMethod;
...
mTexView.setMovementMethod(new ScrollingMovementMethod());
а ScrollView - убрать.
Пример на основе Skeleton App из Android SDK. Вместо EditText добавить TextView:
В итоге получаем до прокрутки:
и после прокрутки:
Ответ 2
Всё логично - TextView при большом размере вытесняет кнопки с экрана.
Можно всё сделать в RelativeLayout
Либо можно оставить LinearLayout и задать TextView атрибут android:layout_weight="1".
Первый вариант лучше, т.к. требует создания меньшего количества View.
Примерно на эту тему есть ещё статья от Romain Guy.
Ответ 3
Попробуй так:
Обрати внимание на:
android:layout_height="0dp" и
android:layout_weight="1" в ScrollView
Добрый день!
Пытаюсь разобраться с GridLayout. Вроде удобная штука, но...
Стоит простая задача на экран вывести 2 ImageButton, но так чтобы их размеры растягивались
самостоятельно на экране.
По логике с этим должен справляться GridLayout. Не могу понять какое свойство настраивать...
Пока съезжают картинки, так как левая больше и сама она не уменьшается.
P.s. размеры картинок не меняю, так как на разных устройствах размер разный, стало
быть как-то это свойствами можно сделать. Только не знаю как...
Ответы
Ответ 1
Тут все несколько нетривиально, хотя ничего военного. Проблема в том что GridLayout
научился разбивать пропорционально (использовать вес) только с версии Android v21.
К счастью GridLayout есть в support library, его только нужно подключить:
для этого нужно подключить сам модуль gridlayout из каталога androidSdk/extras/android/support/v7/gridlayout,
android-support-v7-gridlayout.jar который лежит в папке libs у этого модуля, и android-support-v4.jar.
UPD:
Если использовать Android Studio то подключить их совсем просто, в файле build.gradle
у модуля app:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:support-v4:22.0.0'
compile 'com.android.support:gridlayout-v7:22.0.0'
}
UPD2:
Также предварительно нужно в SDK Manager выкачать последние Tools (Tools, Platform-tools,
Build-tools), Android SDK и Android Support Repository (в низу списка).
Сам xml:
Почему-то не отображается кнопка при программном написании кода, хотя тот же TextView
исправно отображается. В чем может быть проблема?
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
TextView tv = new TextView(this);
tv.setText("TextView");
tv.setLayoutParams(params);
layout.addView(tv);
Button btn = new Button(this);
btn.setText("Button");
btn.setLayoutParams(params);
layout.addView(btn);
setContentView(layout, params);
}
}
Ответы
Ответ 1
Проблема в том, что первая добавленная вами View (TextView) занимает всё пространство
контейнера и для кнопки не осталось места. Вы это задали через LayoutParams.MATCH_PARENT.
Засим вам надо заменить MATCH_PARENT на WRAP_CONTENT
Есть layout, в который в процессе работы приложения могут быть добавлены view или
удалены из него. Может случится так, что все view из layout будут удалены. Можно ли
как-то проверить, пуст ли layout?
Примерно так:
if (R.id.layout1 == (пуст ?) ) {что-то там происходит}
Ответы
Ответ 1
Просто проверьте кол-во детей вашего контейнера. Если оно 0 - значит он пуст.
long birthTimeInMills = System.currentTimeMillis();
SomeContainerLayoutClassName someLayout = new SomeContainerLayoutClassName(context);
int numOfChildren = someLayout.getChildCount();
if(numOfChildren == 0)
{
long lifeTimeInMills = System.currentTimeMillis() - birthTimeInMills;
System.out.println("Контейнеру уже " + lifeTimeInMills + " миллисекунд, а у него
всё ещё нет детей");
}
Мне нужно поднять активити вверх на 15% от высоты экрана(вне зависимости от того
какой экран, элемент должен подняться на 15%) за пределы видимости экрана... Я делаю
это таким образом
Вот у меня есть кастомная вьюха
/.../
/.../
вот здесь я устанавливаю параметры, чтоб это сделать
private void initVar() {
// Margin set in % of the screen
int marginLeft = 0;
------> int marginTop = 15; вот здесь я указываю процент от высоты экрана
int marginRight = 0;
int marginBottom = 0;
// Здесь мы получаем высоту и ширину экрана
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
screenWidth = size.x;
screenHeight = size.y;
// Здесь мы устанавливаем параметры для нашего вью
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
param.setMargins((screenHeight * marginLeft) / 100, -((screenHeight * marginTop)
/ 100),
(screenHeight * marginRight) / 100, (screenHeight * marginBottom) / 100);
mTextureView = (AutoFitTextureView) findViewById(R.id.texture);
mTextureView.setLayoutParams(param);
и вот что получается, когда я загружаю это все дело на телефон Samsung S5 1980x1080
то это выглядит как я и рассчитываю, ровно 15% занято(белая полоса снизу это дефолтный
цвет экрана который открывается когда мы поднимаем вью)
Но когда я тот же проект загружаю на эмулятор 1280x800 то почему то экран поднимается
не на 15% а на 25-30%(точно не на 15%)
А если попробовать на эмуляторе с разрешением 1440*2560, то получается вот так
На первом скриншоте белая полоса не доходит до надписи "Front picture", а на втором
захватывает его и даже больше а на а на третьем это вообще 50% экрана...
Очень странно получается потому что формула по которой идет расчет подразумевает,
что я беру высоту экрана и получаю от нее ровно 15%...
Почему на одном устройстве это 15%, а на другом это больше а на третьем это вообще
50% экрана??
Что я делаю не так??
Вот скриншот на котором margin установлены на 0 и на экране не должно быть белой
полосы, но она есть, хотя на реальном девайсе ее нет...
Ответы
Ответ 1
Вам нужно учитывать плотность экрана. Данные (ширина и высота) дисплея из системы
вам выдают в пиксилях и они реальны. Но когда вы указываете в коде дополнительные цифры,
их нужно пересчитывать под плотность экрана.
К примеру, вы хотите добавить 15 пикселей высоты для вьюшки. Вы берете view.getHeight()
и получаете размер в пикселях и когда прибавите просто число view.getHeight() + 15,
на экранах с разной плотностью эффект быдет выглядеть по разному, где нормально, где
меньше. Но выполнив view.getHeight() + dpToPx(getActivity(), 15). Ваши 15 пикселей
пересчитаются в реальные пиксели для вашего экрана.
public static int dpToPx(Context context, float dp) {
// add 0.5 to round up
return (int) ((dp * context.getResources().getDisplayMetrics().density) + 0.5);
}
public static int pxToDp(Context context, int px) {
// add 0.5 to round up
return (int) ((px / context.getResources().getDisplayMetrics().density) + 0.5);
}
UPD
Технически у вас расчеты правильны. За исключением того, что вы берете расчет высоту
всего экрана. У вас не учитывается высота софтварных кнопок (бек\хом\таск) берите высоту
вашего контейнера, а не высоту экрана. Так как высота контейнера известна только после
ее создания, вешайте лайоут обсервер (к примеру в onCreate).
ViewTreeObserver viewTreeObserver = mViewRoot.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int viewHeight = mViewRoot.getHeight();
mViewRoot.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// тут все ваши расчеты
}
});
mViewRoot - это Ваш рутовый контейнер. И все равно при расчетах в % у вас будут отличаться
цифры, а значит оно не будет выглядеть одинаково на всех устройствах(я правильно понимаю?
что кнопка фото у вас статичного размера :)). Я бы рекомендовал выставить в xml нужную
высоту в для нижней view (mTextureView) , и изменять в пропорциях размер превью камеры
(на остаток высоты) ;)
Ответ 2
Попробуйте вот так высоту/ширину экрана получать:
public static int getWidth(AppCompatActivity act)
{
DisplayMetrics displaymetrics = new DisplayMetrics();
act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
return displaymetrics.widthPixels;
}
public static int getHeight(AppCompatActivity act)
{
DisplayMetrics displaymetrics = new DisplayMetrics();
act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
return displaymetrics.heightPixels;
}
Ответ 3
На вашем месте, я бы наверно начал действовать так же. Но сейчас уже есть готовое
решение из коробки appcompat.
Это PercentRelativeLayout который позволяет задавать размеры дочерних вью в процентах.
С каждым нажатием кнопки "+ Новий елемент" llElement должен дублироваться. Не знаю
как правильно описать именно этот процесс в activity. Должно примерно получиться так,
как на скриншоте выделено красным.
xml:
Ответы
Ответ 1
Если вы хотите сделать именно таким образом, то вынесите
В отдельный xml файл. И добавляйте его или через include (в xml), либо так (программно):
View v = LayoutInflater.from(YourActivity.this).inflate(item.xml, null)
myContainerForViews.addView(v);
myContainerForViews - пустой LinearLayout добавленный вместо удаленного.
Причем ваши View лучше добавлять в ArrayList, чтобы потом иметь доступ к их элементам
через views.get(position).findViewById(R.id.etElement).
НО. Это не самое лучшее решение и не самая правильная организация кода.
Рекомендую вам переделать всё под RecyclerView, в котором вы используете вашу разметку
как item, и массив данных. Тогда добавление и обновление данных будет простым и элегантным:
myList.add(new Item());
recycler.getAdapter().notifyDataSetChanged();
Но если вам просто "надо написать чтобы все работало" сработает и первый вариант.
Только учитывайте, что при n-элементе ваши остальные View (и кнопка) уйдут за экран.
Поэтому придется оборачивать все в ScrollView
Ответ 2
Я бы предложил вам оформить этот участок программы в виде RecyclerView. Тогда добавление
нового элемента будет выполняться через адаптер, и вы сможете считывать данные с этой
ячейки, а не просто добавить ее на экран. Вот неплохой пример https://www.androidhive.info/2016/01/android-working-with-recycler-view/,
но если что, вы без труда найдете кучу других.
Пытаюсь сделать приложение, которое будет показывать наверху в заголовке фото (для
красоты), потом на нижней границе заголовка FloatingActionButton (для показа списка
всех BLE beacon, найденных рядом) и внизу две строчки текста (имя и MAC-адрес выбранного
BLE beacon) и кнопку "Удалить".
Bluetooth-код работает хорошо, а вот с layout не могу разобраться, пожалуйста, помогите.
Я отметил красными стрелками, куда собственно должны встать элементы:
Вот мой activity_main.xml, почему layout_gravity="bottom" не опускает 2 строчки текста
и кнопку вниз?
И styles.xml:
ОБНОВЛЕНИЕ:
Перешел на RelativeLayout, как предложено в этом ответе, но не понимаю, как опустить
кнопку "Delete" вниз - чтобы лучше использовать место на экране:
Ответы
Ответ 1
UPD2
В библиотеке поддержки добавилось несколько новых компоновочных контейнеров:
PercentRelativeLayout и PercentFrameLayout (библиотека android.support:percent) -
компоновщики имеют все те же атрибуты, что и их "родители", кроме того появилась возможность
указывать отступы, расстояния и размеры для вложенных в контейнер виджетов в процентах
от размеров самого контейнера. Пример
FlexboxLayout (библиотека com.google.android:flexbox) - по свойствам схож с LinearLayout,виджеты
располагаются друг за другом, однако имеет существенное отличие - когда виджеты доходят
до границы контейнера, они переносятся "на следующую строку", а не теряются за его
границей (аналогичен FlowLayout на десктопе). Так же имеет несколько атрибутов позиционирования
и взаиморасположения виджетов между собой и в контейнере. Пример
ConstraintLayout - (библиотека поддержки android.support.constraint:constraint-layout)
- контейнер похож на RelativeLayout, поддерживается только начиная с Android Studio
2.2, где для его использования переписали визуальный редактор.
Принцип позиционирования основан на "резиновой" верстке, где вы можете указать расстояния
между виджетами, границы для них и взаимное расположение, при этом относительные размеры
в верстке будут сохранятся при поворотах или разных размерах и плотностях экрана
Описать это очень сложно, поэтому скриншот должен внести ясность. В виду повышенной
сложности Google даже сделала официальный анимированный туториал по использованию
UPD
Существует отдельная группа контейнеров, не так давно добавленная гугл в виде библиотек
поддержки, которые относятся не столько к компоновщикам элементов на экране, сколько
к организации их взаимодействия между собой.
Например, CoordinatorLayout используется для анимированного взаимодействия элементов.
Всякие выдвигающиеся или там всплывающие штуки.
По сути это FrameLayout с возможностями связывания элементов в динамике.
Он позволяет связывать двигающиеся элементы внутри себя так, что они не теряют связи
при движении и могут взаимодействовать. Использовать можно в любых типах анимации,
например всплывающий SnackBar - при его появлении остальные элементы смещаются, чтобы
он не перекрывал их или выдвигающаяся при скроллинге вниз картинка.
Так как это модифицированный FrameLayout, то для группировки элементов внутри него,
если их несколько, необходимо использовать другие контейнеры, чтобы разместить элементы
так, как требуется.
В общем то аналогичного поведения можно добиться и при использовании основных контейнеров,
но ранее для этого приходилось их определенным образом модифицировать, как, например,
в этом ответе - теперь гугл сделала собственный механизм, включенный в API Android.
Основной ответ
FrameLayout не подходит для выбранной вами компоновки, так как этот контейнер (по
умолчанию) размещает все вложенные в него элементы в верхний левый край, с наложением
одних на другие.
Это самый простой из контейнеров и позиционирование внутри него ограничено свойством
gravity, то есть кроме верхнего левого края, элементы можно разместить по центру или
привязать к другим краям (правый, верх, низ), также возможны отступы от краев - padding
и\или margin - на этом возможности компоновки в данном контейнере заканчиваются.
Как видите этого недостаточно для размещения элементов последовательно - один за
другим, либо еще какого-то относительного связывания вложенных элементов между собой
внутри данного контейнера.
Для более сложных компоновок используются контейнеры:
LinearLayout- вложенные элементы идут друг за другом по вертикали или горизонтали.
TableLayout - вложенные элементы размещаются в структуру таблицы. По сути это горизонтальные
LinearLayout вложенные в вертикальный LinearLayout в более удобном представлении. Поскольку
ячейки таблицы могут иметь разный размер и в каждой строке может быть разное количество
ячеек, то с его помощью можно скомпоновать довольно сложные разметки,составные элементы
которой можно разбить на ячейки ( а это почти все в реальности)
GridLayout - технически повторяет TableLayout, но более функциональный и имеет дополнительные
возможности в части позиционирования элементов ( можно указать номер конкретной ячейки,
где разместить элемент), также позволяет размещать несколько элементов в одной ячейке
и некоторые другие возможности.
RelativeLayout - вложенные элементы связываются друг с другом линками между собой
и\или границами контейнера - это самый сложный (и самый ресурсоемкий) компоновщик,
позволяет практически произвольно размещать элементы внутри себя, в том числе и с наложением
один на другой, без центровки по осям и прочие чудеса.
Существует еще несколько менее популярных контейнеров на которых я останавливаться
не буду.
Выбирать контейнер надо из соображений достаточной функциональности. Выше они расположены
в порядке приоритета, то есть если для компоновки достаточно LinearLayout, то использовать
RelativeLayout будет излишним расточительством ресурсов устройства, так как это намного
более ресурсоемкий контейнер.
Отдельно нужно заметить по поводу вложения одного контейнера в другой - если есть
возможность скомпоновать виджеты в один контейнер, то это предпочтительнее, чем использовать
вложенные контейнеры, то есть RelativeLayout будет предпочтительнее трех вложенных
LinearLayout, чем линейней получается структура компоновки, тем лучше для производительности,
как правило.
Ответ 2
К кнопке delete добавь свойство android:layout_alignParentBottom="true"
У меня есть FrameLayout в который я кладу Button и FrameLayout с целью перекрыть
изображением (будущей анимацией, поэтому и FrameLayout) кнопку. Предпросмотр все отображает
верно:
Однако, при запуске кнопка перекрывает "FrameLayout":
Вот разметка:
Почему Button перекрывает FrameLayout (хотя с аналогичной... конструкцией, в этой
же разметке, такого не было. И как все же расположить FrameLayout поверх Button?
Ответы
Ответ 1
Вся соль здесь в таком атрибуте кнопки как android:elevation.
Кнопка в API > 21 имеет такой атрибут android:stateListAnimator, который по умолчанию
ссылается на файл button_state_list_anim_material.xml со следующим содержанием:
...
...
Видим что в обычном state_enabled-состоянии атрибут elevation имеет значение @dimen/button_elevation_material,
которое равно 2dp.
Вывод: если мы хотим что бы какое то view перекрывало кнопку, необходимо для него(view!)
использовать android:elevation >= 2dp.
Ответ 2
Оберните кнопку и фрейм дополнительно отдельными лайатуами, я уже у себя ловил такой
баг, когда поверх Button на андройде 5.0 и выше вью которая должна была рисоваться
поверх не было видно. Пока не добрался до причины, но костыльно решено было вот так.
Возможно только что, до меня дошло... AppCompat переопределяет во вью при создании
стандартные виджеты и ставит свои (AppCompatButton, AppCompatTextView и др. - замечал
при дебаге), так как они удаляют и добавляют, виджет Button будет иметь индекс больше
чем FrameLayout, а соответственно выше по иерархии и в итоге после всех этих махинаций
гугла - виджет Button лежит по верх всего остального в общем контейнере. Поправьте
меня в комментарии, если это бред.
Закрыт. Этот вопрос не по теме. Ответы на него в данный
момент не принимаются.
Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он соответствовал тематике «Stack Overflow на русском».
Закрыт 2 года назад.
Вот код
window.onload = window.onresize = function() {
this.timeout && clearTimeout(this.timeout);
this.timeout = setTimeout(function() {
var image = document.getElementsByTagName('img')[0];
document.documentElement.style.fontSize = image.offsetHeight + '%';
}, 10);
}
html, body {
height: 100%;
width:100%;
margin: 0;
}
.table {height: 100%; width:100%; display:table;}
.column {
height: 100%;
display: table-cell;
border: 1px solid green;
vertical-align: top;
}
.column-img {
display: table-cell;
height: 100%;
background: red; /* for debugging */
}
img {
display: block;
height: 100%;
}
Content DIV, here will be tables and some another content
работает в IE9, Android Browser и т.п.
Слева - резиновый отступ, справа - div с контентом.
Ширина отступа зависит от высоты вьюпорта, поэтому сделал через gif-распорку с нужными
пропорциями.
Распорка и контент должны по высоте быть 100% от вьюпорта, контент занимает все место
справа.
Если сильно сжать в высоту пример, то вылезает дополнительный глючный отступ красного
цвета.
Как сделать, чтобы его не было?
Есть просьба не предлагать верстать в JS...
Спасибо.
UPDATE На старом CSS без vh units задачу решить невозможно. Сделал на Javascript.
Закрываю ответ - либо js, либо vh units (ныне работает везде)
Ответы
Ответ 1
Глюк браузера, .column-img {5px}, а img{5px}, только перерисовка в браузере спасет.
Обновление
Если убрать display: block; и добавить, то браузер перерисует опять страничку, и
отступ исчезнет. Возможно, проблема в font-size, боюсь, тут поможет эксперимент, т.к.
используется хак с gif картинкой, чего, конечно, нет в спецификациях. ;) Попробуйте
"поиграть с изменением размера".
Рассмотрим то, что мне нужно, на примере этого котика:
Допустим, в моём приложении этот котик представляет собой атрибут background в корневом
layout в файле main_activity.xml.
Во-первых, если экран устройства меньше, чем котик, то котик должен сжиматься, но
никак не обрезаться. Причём так, чтоб на экране не оставалось пустого места. То есть:
Так-то оно и по умолчанию происходит, но есть одно больше во-вторых: все view-элементы
на экране тоже должны сжиматься и оставаться на той части котика, на которой они были
изначально, то есть:
В общем, это всё, что мне нужно, но так должно быть на каждом устройстве, учитывая
планшеты.
Я много читал в интернете про все эти экранные дела, но там нету целостной картины.
А мне нужна полная последовательность действий:
какие нужно создавать layout'ы?
какие к ним нужны подпапки drawable?
какого разрешения делать котиков?
писать ли что-то в AndroidManifest?
и что-то ещё, чего я не знаю..?
Ответы
Ответ 1
Требуемого вами поведения можно в основном добиться, используя следующую разметку:
Котик заполняет собой все место - и в альбомной и в портретной ориентации. Проверено
на телефоне и планшете. Надпись распологается на одном и том же месте котика.
Если искать несоответстие, то это не совсем пропорциональное изменение размера текста
(особенно заметно по ширине). Тут конечно тоже можно было бы повозиться и пересчитать
размер шрифта, исходя из числа пикселей экрана. И назначить этот размер шрифта программно.
Но мне кажется, не стоит так напрягаться, так как результат вполне сносный. Если лезть
в такие дебри, то потом возникнут проблемы типа: а что если текст не поместится в одну
строку? и т.д.
По поводу разных плотностей. Картинка благополучно растянулась под размер экрана
и на телефоне и на планшете. Оба устройства с нормальной плотностью. Для высокой плотности
неплохо было бы предоставить картинку побольше. Для низкой плотности - поменьше, чтобы
занимала меньше места, и не было артефактов изображения при обработке слишком детализированного
изображения для экрана, где мало пикселей, хотя, может, это и лишнее.