Страницы

Поиск по вопросам

четверг, 27 декабря 2018 г.

Слушатель выделения для ListView

Скажите, есть ли слушатель выделения элемента у ListView? Искал в гугле (на русском), но нашел только onClickListener'ы и тому подобные. Они реагируют на нажатие (когда палец отпустили), а мне нужно, чтобы слушатель реагировал на начало прикосновения к пункту списка, а потом на его отпускание. Есть такой слушатель предназначенный именно для ListView (а не onTouch)?


Ответ

Полагаю, что ваше решение - onTouchListener. Может и момент нажатия поймать, и момент отпускания.
OnTouchListener listener = new OnTouchListener() {
@Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //something break; case MotionEvent.ACTION_UP: //something } return true; } };
view.setOnTouchListener(listener);

Доступ к getAssets () из другого статического класса

Он работает с моей основной Activity и моим фрагментом, но если я использую метод LoadSound() в Sound классе, то getAssets() не работает.
public class CarnivoreFragment extends Fragment {
private int mCowSound; private View view;
private ImageButton mCowImageButton;
public CarnivoreFragment() { }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_carnivore, container, false);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Sound.createOldSoundPool(); } else { Sound.createNewSoundPool(); }
mCowSound = Sound.loadSound("cow.wav");
mCowImageButton = (ImageButton) view.findViewById(R.id.imageButtonCow); mCowImageButton.setOnClickListener(onClickListener);
return view; }
View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.imageButtonCow: Sound.playSound(mCowSound); Toast.makeText(view.getContext(), "Cow", Toast.LENGTH_SHORT).show();
break;
} } }; }
И мой класс "Sound":

public class Sound {
private static SoundPool mSoundPool; private static AssetManager mAssetManager; private static int mStreamID; private static Context context;
public Sound(Context context) { this.context = context; }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) public static void createNewSoundPool() { AudioAttributes attributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_GAME) .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .build(); mSoundPool = new SoundPool.Builder() .setAudioAttributes(attributes) .build(); }
@SuppressWarnings("deprecation") public static void createOldSoundPool() { mSoundPool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0); }
public static int playSound(int sound) { if (sound > 0) { mStreamID = mSoundPool.play(sound, 1, 1, 1, 0, 1); } return mStreamID; }
public static int loadSound(String fileName) { mAssetManager = context.getAssets(); AssetFileDescriptor afd; try { afd = mAssetManager.openFd(fileName); } catch (IOException e) { e.printStackTrace(); Toast.makeText(context, "Не могу загрузить файл " + fileName, Toast.LENGTH_SHORT).show(); return -1; } return mSoundPool.load(afd, 1); }
}
Как решить эту проблему?


Ответ

Если создание экземпляров класса не входит в алгоритм использования класса Sound (так как все поля и методы в нем статические), то ваши методы не смогут получать контекст (так как конструктор не отрабатывает), который необходим для работы метода getAssets() В качестве решения можно предложить передавать контекст через параметры метода, в котором он требуется:
public static int loadSound(Context context, String fileName) { mAssetManager = context.getAssets(); .... }
Вызов из фрагмента:
mCowSound = Sound.loadSound(getActivity(), "cow.wav");
Если экземпляра активити будет недостаточно для контекста getAssets(), то нужно использовать другие способы доступа к контексту. Более правильно - получить экземпляр контекста один раз при создании фрагмента и "подсовывать" его везде, где требуется, а не вызывать каждый раз метод его получения.

Перевод строки в десятичное число. Java

Есть такие строки:
0x16 012 0b10 62
Нужно перевести их в:
22 10 2 62
соответственно, но при использовании Integer.parseInt(String, int) получаю NumberFormatException, как решить эту проблему?


Ответ

например, можно написать такую функцию
private static int StringToInteger(String input) { if(input.startsWith("0x")) { return Integer.parseInt(input.substring(2), 16); } else if(input.startsWith("0b")) { return Integer.parseInt(input.substring(2), 2); } else if(input.startsWith("0") && input.length() > 1) { return Integer.parseInt(input.substring(1), 8); } else { return Integer.parseInt(input); } }

Как стилизовать элемент счетчика?

  • 24

  • Как можно получить такой элемент как на картинке с помощью css (белая полоска зачеркивания идет перед цифрой)?
    P.S.: цифры при этом меняются динамически


    Ответ

    span { display: inline-block; background: #ffd800; font: 20px/1 Arial; width: 20px; border-radius: 5px; } span:before { content: ''; display: block; position: relative; top: 11px; left: 0; width: 20px; height: 2px; background: #fff; } 24

    Кастинг в коде это нормально?

    Кастинг в коде это нормальное явление или повод задуматься над тем что, что то с кодом не так?


    Ответ

    Кастинг, кастингу рознь. К примеру, если у вас в коде есть static_cast, то это может быть подозрительно, но вряд-ли опасно. Тем не менее, даже со static_cast нужно убедиться, что это не просто безответственная попытка «заткнуть» компилятор, а явное и нужное преобразование. Как правило, такие вещи нужны на стыке кода библиотек, но, в идеальном случае лучше избегать и static_cast
    Если у вас в коде появляется dynamic_cast, то есть вероятность, что вы неправильно используете полиморфизм. Тем не менее, с точки зрения корректности программы, dynamic_cast не является проблемой. Он не может ничего такого добавить, чтобы сделало программу некорректной(т.е. он не служит «затычкой» компилятора). Поэтому наличие dynamic_cast может служить признаком неправильного дизайна(и пессимизации), но не более того.
    Если у вас в коде есть const_cast, то наиболее вероятно, что у вас в коде имеет место ошибка дизайна, которая должна быть исправлена как можно скорее. В противном случае вы сами знаете, что делаете и const_cast там не случаен. Прибегать к нему стоит лишь в том случае, когда других вариантов уже не осталось. И даже в этом случае стоит 100 раз всё обдумать и взвесить, т.к. const_cast не снимает константность с объектов, которые были рождены таковыми изначально. Точнее он может снять, а может и не снять — UB, если не ошибаюсь будет в этом случае.
    Наконец, если у вас в коде есть reinterpret_cast и он не находится в коде, который работает на стыке кроссплатформенного модуля и модуля специфичного конкретной ОС, то у вас с большой долей вероятности есть проблема.
    Если же у вас в коде есть C-style касты, то, сначала, замените их на C++ аналоги, а потом удалите те, что не являются необходимостью.
    В целом, любой оператор явного преобразования является потенциальной проблемой, поэтому их использование желательно свести к минимуму. Каждое такое использование должно иметь смысл и быть необходимым.

    Как правильно обработать порядок арифметических операций?

    Делаю что-то вроде обработчика выражений, как в Excel...
    Есть входящая строка String inputStr = "5+5-10/8+8*2" (любые числа и действия).
    Как реализовать приоритет действий? Нужен алгоритм.


    Ответ

    Эта задача решается с использованием стека через формирование и подсчёт Обратной Польской Нотации .

    Как из String сделать &str (возникает ошибка времени жизни ссылки)

    Написал функцию:
    fn read_str<'a>() -> &'a str { let mut input = String::new(); io::stdin().read_line(&mut input).ok(); let output : &str = &input[..]; &output }
    При компиляции возникает ошибка
    src/main.rs:13:26: 13:31 error: `input` does not live long enough src/main.rs:13 let output : &str = &input[..]; ^~~~~ src/main.rs:10:30: 15:2 note: reference must be valid for the lifetime 'a as defined on the block at 10:29... src/main.rs:10 fn read_str<'a>() -> &'a str { src/main.rs:11 let mut input = String::new(); src/main.rs:12 io::stdin().read_line(&mut input).ok(); src/main.rs:13 let output : &str = &input[..]; src/main.rs:14 &output src/main.rs:15 } src/main.rs:11:32: 15:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 11:31 src/main.rs:11 let mut input = String::new(); src/main.rs:12 io::stdin().read_line(&mut input).ok(); src/main.rs:13 let output : &str = &input[..]; src/main.rs:14 &output src/main.rs:15 }
    Пробовал брать строку io::stdin().read_line(&mut input).ok(); в фигурные скобки, дабы ограничить &mut, но это не помогает.


    Ответ

    Вернуть из функции можно только ссылку на статический объект (с временем жизни 'static) или ссылку, которую вы получили во входных параметрах.
    Вы пытаетесь вернуть ссылку на объект созданный в стеке функции. После завершения функции все объекты в стеке будут уничтожены. Rust не позволит создать ссылку на объект, который она может пережить. Использование после освобождения (use after free)
    В вашем случае лучше всего вернуть String. Накладные расходы в этом случае невелики, так как почти вся информация внутри строки хранится в куче.

    Большинство проблем начинающих писать на Rust связаны с непониманием назначения различных типов указателей. Если не вдаваться в подробности, их там можно насчитать пять штук.
    Ссылки в Rust используются для передачи данных без передачи права владения. Например если у вас есть структура, в которой хранится строка:
    struct Person{ name:String }
    то выдавать информацию о ее содержимом лучше так:
    impl Person{ pub fn get_name(&self)->&str{ &self.name } }
    или можно вернуть копию строки:
    pub fn get_name_clone(&self)->String{ self.name.clone() }
    Но это приведет к дополнительным расходам на копирование строки. Расходы здесь возникают именно из-за копирования - вызова метода clone(), который создает вторую копию данных строки в куче, а не из-за того, что функция возвращает строку.
    Можно вернуть строку из структуры без копирования:
    pub fn get_name_own(self)->String{ self.name }
    Но после вызова этого метода исходный объект Person перестанет существовать, так как право владения было передано.
    Еще одна распространенная причина проблем - попытка хранить ссылки на другие объекты в структуре. Ссылки накладывают кучу ограничений на время жизни и мутабельность связанных объектов. Прежде чем это делать, стоит дважды подумать о возможности использования других типов указателей.