Страницы

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

среда, 22 января 2020 г.

Выравнивание элементов

#android


Стоит следующая задача. Есть 5 кнопок с фиксированной шириной каждая (могут различаться).
Необходимо разместить их одной строкой с одинаковым зазором между ними (зависит от
разрешения экрана). Можно, ли как то сверстать такое в xml, т.к. программно делать
не хочется.
P.S.: Ширина кнопок меняться не должна. Надо менять именно зазор между ними.    


Ответы

Ответ 1



Да, можно такое сделать с помощью свойства LinearLayout - weightSum Тебе необходимо создать LinearLayout c weightSum = 5, затем для каждого child указать layout_weight = 1. Таким образом ширина LinearLayout разделится поровну на 5 частей и каждый child будет иметь ширину, равную одной пятой родительской ширины.

Ответ 2



Нужно поместить их в LinearLayout с горизонтальной ориентацией и для каждой кнопки задать для каждой кнопки опступы(margins). Здесь подробно написано.

Ответ 3



Зачем нужны пространства имён в PHP

#php #namespace


Здравствуйте!
Меня интересует, в чем преимущество использования namespace в php?
Сейчас у меня все классы подключаются через автолоад и классы размещены в соответствии
с PSR-0, тоесть класс ClassParent_Class_ClassChild находится в /classes/ClassParent/Class/ClassChild.php
Если использовать namespace, то для меня изменится только то, как я буду вызывать класс:
как сейчас - ClassParent_Class_ClassChild, или с namespace \ClassParent\Class\ClassChild
(об алиасах я знаю, но не считаю это преимуществом)
Не исключено, что я чего-то не понимаю. Поэтому и задал вопрос.    


Ответы

Ответ 1



Очень хорошая статья на этот счет! И конкретно по вашему вопросу, отвечаю комментарием из статьи: используя пространство имен, мы гарантируем существование наших библиотек (моего кода и стороннего) в абсолютно разных пространствах, что означает — вообще никто никого затирать не будет.

Как проверить, что поток NSThread заблокирован?

#objective_c #многопоточность #posix #pthread


Давно хотел узнать, возможно ли для тестирования (unit testing) сделать следующее:
Можно ли добавить в NSThread метод, который будет показывать, заблокирован (остановлен)
ли данный поток или нет?
Я предполагаю, что, если эта задача в принципе решается, было бы удобно сделать отдельную
категорию NSThread+IsBlocked, содержащую такой метод и вполне достойную своего отдельного
репозитория на Github ;)
Прямо сейчас я занимаюсь NSCondition - вот цепь вызовов, которую для остановки потока
делает -[NSCondition wait]:
[NSCondition wait] 
pthread_cond_wait$UNIX2003
_pthread_cond_wait
__psynch_cvwait

Кроме NSCondition есть множество других способов блокировать/останавливать потоки
NSThread: dispatch semaphores, NSConditionLock, [NSThread sleepForTimeInterval:] и
т.п. - я знаю Objective-C лишь на уровне iOS-разработчика, поэтому не имею представления,
возможно ли написать такой метод, который будет показывать факт блокировки потока сразу
для всех этих способов. Буду признателен даже за метод, работающий только с NSCondition
и __psynch_cvwait.
Вот простой пример того, чего я хотел бы добиться (искомый метод - isBlocked):
// Some test case
// ...

__block NSThread *thread;
NSCondition *condition = [NSCondition alloc] init];

dispatch_async(someQueue(), ^{
    thread = NSThread.currentThread;

    [condition lock];
    [condition wait];
    [condition unlock];
});

while(1) {
    NSLog(@"Thread is blocked: %d", thread.isBlocked);
}

Я не знаток чистого C и POSIX threads, поэтому, если знаете ответ, сделайте его,
пожалуйста, развёрнутым.
Примечание: речь идёт именно о блокировании (остановке) потока, а не о проверке isLocked
вроде "Находимся ли мы @synchronized {}?"     


Ответы

Ответ 1



Мир - Россия 1:0 - ответ получен в топике, который параллельно с этим был открыт мной на SO: Is it possible to check if an NSThread is blocked?. Там см. принятый ответ. Очень изящное решение для NSCondition. Заодно показывающее, как можно красиво модифицировать поведение классов, подменяя методы друг другом (по логике отдалённо напоминает alias_method_chain в Ruby).

Альтернатива модульному программированию

#c #модульность #cpp


Какие существуют альтернативы, разделению кода на модули? То есть интересует вопрос
в подходе к проектированию самой архитектуры, а не использование каких либо особенностей
конкретной среды разработки или оптимизации кода(вроде удаления шаблонов).
Например .h .cpp в С++.

Основная цель: повышение скорости
компиляции. 
Дополнительная цель:
удобство использования.

@Flammable    


Ответы

Ответ 1



Вы думали о инкапсуляции?:) подумайте. Я бы например не хотел видеть в своей программе реализацию printf(). Раздельная компиляция повышает скорость раз в десять, если у вас 10 модулей и один вы исправили, то компилируется только исправленный. Эта архитектура не остаток от прадедов в наследство, это опытом и десятилетиями проверенный и наработанный метод. В конце концов, а если часть программы будет разрабатывать кто то другой? Все в одном месте?

Кривая Безье произвольного порядка.

#математика #алгоритм #php


Товарищи программисты-математики, отдаю на ваш справедливый суд данный класс.
Некоторые очевидные методы, вроде lineTo я убрал, чтобы не было tl;dr, то есть, это
выжимка интересующих меня моментов.
x = $x?$x:rand(1,IMG_SIZE_X);
        $this->y = $y?$y:rand(1,IMG_SIZE_Y);
    }

    /**
     * @param point $p
     * @param float $dist
     *
     * @return point
     */
    function midPoint(point $p,$dist=0.5){
        $new_x = $this->x+($p->x-$this->x)*$dist;
        $new_y = $this->y+($p->y-$this->y)*$dist;
        $new_point = new point($new_x,$new_y);
        return $new_point;
    }
}

/**
 * Class bezierimage
 */
class bezierimage{
    private $img;
    public $color;
    public $bgcolor;
    public $brush_position;
    function __construct(){
        $this->img = imagecreatetruecolor(IMG_SIZE_X,IMG_SIZE_Y);
        $this->color = imagecolorallocate($this->img,255,255,255);
    }

    /**
     * @param point[]   $points
     * @param float     $dist
     *
     * @return point[]
     */
    function getBezierPoints($points,$dist=0.5){
        if(count($points)==1){
            return $points[0];
        }
        $new_points = array();
        for($i=1;$imidPoint($points[$i],$dist);
        }
        return $this->getBezierPoints($new_points,$dist);
    }
    /**
     * @param point[]   $points
     * @param int       $precision
     */
    function bezierCurve($points,$precision=700){
        foreach($points as $point){
            $this->putPixel($point);
        }
        for($i=0;$i<$precision;$i++){
            $dist = $i/$precision;
            $this->lineTo($this->getBezierPoints($points,$dist),2);
        }
    }
}

Можно ли, не прибегая к другим языкам, оптимизировать данный код? Он заметно начинает
тормозить уже на порядке 70, а на 100 просто утыкается в ограничение по вложенности
рекурсии. Особенно интересуют два момента:
метод getBezierPoints - оптимизация
метод bezierCurve - динамический подбор количества полигонов, в зависимости от кривизны
линии на данном отрезке.

По поводу сторонних библиотек: к сожалению, чаще всего находятся максимум 3-4 порядка,
так что не вариант, разве что собрать свою.
P.S. таки да, я опять пытаюсь использовать PHP в целях, для которых он не предназначен.
Но интерес больше академический, для практики и правда более 6-10 точек не надо.    


Ответы

Ответ 1



По поводу getBezierPoints — можно сделать в один проход без рекурсии. Смотрите. Пусть в начале у нас есть точки p[0], ..., p[n-1]. После первого шага у нас получается q[0] = (p[0] + p[1]) / 2, q[1] = (p[1] + p[2]) / 2, ..., q[n-2] = (p[n-2] + p[n-1]) / 2, то есть q[i] = (p[i] + p[i+1]) / 2. На следующем шаге r[i] = (q[i] + q[i+1]) / 2 = (p[i] + 2p[i+1] + p[i+2]) / 4. Видно, что возникают биномиальные коэффициенты: r[i] = (C_2^0 p[i + 0] + C_2^1 p[i + 1] + C_2^2 p[i + 2]) / 2^2. (Немного математики: По индукции легко доказать, что биномиальные коэффициенты будут и дальше: если на j-м уровне s[i] = (\sum_k=0^{j-1} C_j^k p[i + k]) / 2^j, то на (j+1)-м t[i] = (s[i] + s[i+1]) / 2 = = (\sum_k=0^j (C_j^k + C_j^{k + 1}) p[i + k]) / 2^{j + 1} = (\sum_k=0^j C_{j + 1}^k p[i + k]) / 2^{j + 1}. База индукции очевидна.) Итак, нам нужны биномиальные коэффициенты. Их можно тоже легко вычислить на лету. Конечный алгоритм должен быть таким: int l = count($points); int coeff = 1; point result = $points[0]; for (int idx = 1; idx < l; idx++) { coeff *= (l - idx); coeff /= idx; result += $points[idx] * coeff; } result /= (1 << (l - 1)); // степень двойки Если делить надо не обязательно на 2, аналогично получается вот что: int l = count($points); double alpha = 0.333333; // или любое другое значение между 0 и 1 double beta = 1 - alpha; double beta2alpha = beta / alpha; int coeff = alpha ** (l - 1); // степень point result = $points[0] * coeff; for (int idx = 1; idx < l; idx++) { coeff *= (l - idx); coeff /= idx; coeff *= beta2alpha; result += $points[idx] * coeff; }

Как организовать мигание вспышки

#android_sdk #camera #eclipse #android


Именю такой код, для включения вспышки
mCamera = Camera.open();
Camera.Parameters params = mCamera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(params);

И такой для выключения
Camera.Parameters params = mCamera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);
mCamera.release();
mCamera = null;

Как организовать мигание вспышки по нажатию ToggleButton. То есть, есть ToggleButton
ON то вспышка мигает, а если OFF то останавливается.
PS. Работать с ToggleButton умею, нужет только код, запускающий мигание.    


Ответы

Ответ 1



Собственно, вот рабочий код. Есть маленький нюанс. Если нажать на кнопку в момент, когда вспышка будет гореть, то она так и останется гореть. Кто захочет, добавит дополнительную проверку или выключение вспышки по завершению цикла. Итак, первым делом обязательно добавляем в файл манифеста строки о доступе к камере и вспышке. По условиям вопроса я добавил на слой простую ToggleButton. Её id - btn_switch . Всё, дальше можно копировать код в своё Activity и наслаждаться морганием. package com.blogspot.leved_notes.blinker; import android.app.Activity; import android.content.pm.PackageManager; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.os.Bundle; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.Toast; import android.widget.ToggleButton; public class MainActivity extends Activity implements OnCheckedChangeListener { ToggleButton mSwitcher; private Camera mCamera; private Parameters mParams; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSwitcher = (ToggleButton) findViewById(R.id.btn_switch); mSwitcher.setOnCheckedChangeListener(this); if (!checkCameraHardware()) gameOver(); mCamera = getCameraInstance(); checkFlash(); } @Override public void finish() { super.finish(); if (mCamera != null) mCamera.release(); } @Override public void onCheckedChanged(CompoundButton btn, boolean state) { if (state) { Thread thread = new Thread(new Runnable() { @Override public void run() { if (mCamera != null) { while (mSwitcher.isChecked()) { String mode = mParams.getFlashMode(); if (mode.equals(Parameters.FLASH_MODE_OFF)) mode = Parameters.FLASH_MODE_TORCH; else mode = Parameters.FLASH_MODE_OFF; mParams.setFlashMode(mode); mCamera.setParameters(mParams); try { Thread.sleep(500L); } catch (InterruptedException e) { e.printStackTrace(); } } } } }); thread.start(); } } /** Check if this device has a camera */ private boolean checkCameraHardware() { boolean result = false; PackageManager pm = getPackageManager(); if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA) && pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) { // this device has a camera and flash result = true; } else gameOver(); return result; } private void gameOver() { finish(); Toast.makeText(this, "Error!", Toast.LENGTH_LONG).show(); } /** A safe way to get an instance of the Camera object. */ public Camera getCameraInstance() { CameraInfo info = new CameraInfo(); Camera c = null; for (int i = 0; i < Camera.getNumberOfCameras(); i++) { Camera.getCameraInfo(i, info); if (info.facing == CameraInfo.CAMERA_FACING_BACK) { try { c = Camera.open(i); // attempt to get a Camera instance } catch (Exception e) { e.printStackTrace(); } } } return c; // returns null if camera is unavailable } private void checkFlash() { if (mCamera != null) { mParams = mCamera.getParameters(); } else gameOver(); } }

Java: является ли объектом int[]?

#java


По мотивам "Нюанс при применении метода toString"  

@Barmaley:


  Не все массивы являются объектами,
  скажем int[] не является объектом...


@Антон Феоктистов:


  Barmaley, могли бы подробнее
  рассказать про int[]? А то я сегодня
  даже в книжки полез. У Эккеля сказано,
  что любой массив, это объект, в
  котором хранятся ссылки на объекты.
  Какого-то замечания по примитивам там
  не было. Если int[] не является
  объектом, то и методов length(),
  toString(), hashCode() и т.д. не было
  бы, по идее


Хотелось бы действително узнать по подробнее. Сам я этот язык ещё изучаю и интересны
подобные нюансы.
P.S. Просьба не путать int с int[]. Переменная int как примитивный тип не может являться
объектом. Вопрос именно о принадлежности массива int (int[]) к объектам.
    


Ответы

Ответ 1



Я ошибся. Переменные примитивных типов не являются объектами, а массивы примитивных типов уже объекты: An object is a class instance or an array. Первоисточник здесь