Страницы

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

Показаны сообщения с ярлыком progress-bar. Показать все сообщения
Показаны сообщения с ярлыком progress-bar. Показать все сообщения

пятница, 31 января 2020 г.

Как сделать slick слайдер с горизонтальным прогресс баром?

#javascript #slider #progress_bar #slickjs


Нужно сделать таймер как здесь http://www.apple.com/ 

Слайдер сделан с помощью slick.js, но к сожалению в плагине нет такого таймера. Можно
ли было Speed передавать прогресс-бару?



 $(document).ready(function () {
        $('.slider').slick({
            infinite: true,
            autoplay:true,
            dots: true,
            arrows: false,
            autoplaySpeed: 3000,
            slidesToShow: 1,
            slidesToScroll: 1
        });

    })
.slider .slick-dots {
  padding: 0; }
  .slider .slick-dots li {
    position: relative;
    display: inline-block;
    width: 19%;
    height: 15px;
    margin: 0 2px 0 0;
    padding: 0;
    cursor: pointer;
    background: #ccbdb6;
    transition: width 5s ease-out 0s; }
    .slider .slick-dots li:last-child {
      margin-right: 0; }
    .slider .slick-dots li:hover, .slider .slick-dots li.slick-active {
      background: #a08a7f; }
    .slider .slick-dots li button {
      display: none !important; }

 

1

2

3

4

5


Ответы

Ответ 1



добавлено css $(document).ready(function() { $('.slider').slick({ infinite: true, autoplay: true, dots: true, arrows: false, autoplaySpeed: 3000, slidesToShow: 1, slidesToScroll: 1 }); }) .slider .slick-dots{ padding:0; } .slider .slick-dots li{ position:relative; display:inline-block; width:19%; height:15px; margin:0 2px 0 0; padding:0; cursor:pointer; background-color:#ccbdb6; background-size:100% 100%; background-image:-webkit-gradient(linear, left, right, color-stop(1, rgb(16,56,16)), color-stop(1, transparent)); background-image:-o-linear-gradient(left, rgb(16,56,16) 100%, transparent); background-image:-moz-linear-gradient(left, rgb(16,56,16) 100%, transparent); background-image:-webkit-linear-gradient(left, rgb(16,56,16) 100%, transparent); background-image:linear-gradient(to right,rgb(16,56,16) 100%,transparent 100%); background-repeat:no-repeat; } .slider .slick-dots li:last-child{ margin-right:0; } .slider .slick-dots li:hover,.slider .slick-dots li.slick-active{ background-color:#a08a7f; } .slider .slick-dots li button{ display: none !important; } .slider .slick-dots li.slick-active~li{ background-size:0% 0%; } .slider .slick-dots li.slick-active{ -webkit-animation:right 3s ease-in-out forwards; -moz-animation:right 3s ease-in-out forwards; -o-animation:right 3s ease-in-out forwards; animation:right 3s ease-in-out forwards; } @keyframes right{ 0%{ background-size:0% 100%; } 100%{ background-size:100% 100%; } }

1

2

3

4

5



Ответ 2



Первое, что приходит на ум — это сделать CSS-анимацию. Но в тестах этот вариант показывает себя не с лучшей стороны, поскольку CSS-таймеры и JS-таймеры могут ходить с разной скоростью. К тому же, так у нас появляется две точки управления анимацией, т. е. когда необходимо заменить скорость смены слайдов, надо это делать в CSS и JS. Мой вариант работает на коллбеках, описанные выше проблемы исключены. UPD: заменил анимацию ширины на анимацию масштабирования для увеличения производительности. $(function(){ var speed = 2000, $li; $('.slider').on('init', function(slick) { $(slick.target).find('button').append(''); $li = $(slick.target).find('.slick-dots li'); animateSpan(0, $li); }); $('.slider').slick({ dots: true, autoplay: true, autoplaySpeed: speed }); $('.slider').on('afterChange', function(event, slick, currentSlide, nextSlide) { $li.find('button span').stop(true, true); $li.find('button').removeClass('filled'); if(currentSlide == 0) { $li.find('button span').css({ 'transform': 'scaleX(0)', 'border-spacing': 0 }); } else { // всем до текущего слайда назначить класс, чтобы они были заполнены for(var i = 0; i < currentSlide; i++) { $li.eq(i).find('button').addClass('filled'); } // всем после текущего слайда убрать классы и ширину, чтобы были пустыми for(var i = currentSlide + 1; i < $li.length + 1; i++) { $li.eq(i - 1).find('button').removeClass('filled') .find('span').css({ 'transform': 'scaleX(0)', 'border-spacing': 0 }); } } animateSpan(currentSlide, $li); }); function animateSpan(currentSlide, $li) { var $currentBtn = $li.eq(currentSlide).find('span'); $currentBtn.animate({ borderSpacing: 1 }, { step: function(now, fx) { $(this).css('transform', 'scaleX('+ now +')'); }, duration: speed }, 'linear'); } }) .slider { width: 400px; } .slider__item { padding: 50px; background-color: #666; color: #FFF; font-size: 20px; text-align: center; } .slider ul { margin: 20px; padding: 0; } .slick-dots { text-align: center; } .slick-dots li { list-style-type: none; display: inline-block; } .slick-dots button { width: 25px; height: 10px; margin: 0 2px; border: 0; background-color: #ccc; list-style-type: none; position: relative; font-size: 0; } .slick-dots button span { position: absolute; width: 100%; display: block; height: 100%; background-color: #000; left: 0; top: 0; transform: scaleX(0); transform-origin: left; } .slick-dots button.filled span { transform: scaleX(1) !important; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6


воскресенье, 29 декабря 2019 г.

Progress bar первоначальной загрузки

#android #progress_bar


Подскажите, с помощью чего можно сделать такой прогресс бар.


    


Ответы

Ответ 1



Это стандартный ProgressDialog. Пример: ProgressDialog progressDialog = new ProgressDialog(this); progressDialog.setMessage("Идет поиск рейсов"); progressDialog.show(); Для отмены: progressDialog.dismiss(); Можете обвешать чем необходимо: .setCancelable(false); //не закрывается по тапу вокруг .setTitle("Title"); //Заголовок И много другого, подробно в официальной документации

Ответ 2



AsyncTask c progressdialog'ом Пример: private class NetCheck extends AsyncTask{ private ProgressDialog nDialog; @Override protected void onPreExecute(){ super.onPreExecute(); Context context = getApplicationContext(); nDialog = new ProgressDialog(Activity.this); nDialog.setTitle(""); nDialog.setMessage(""); nDialog.setIndeterminate(false); nDialog.setCancelable(false); nDialog.show(); } @Override protected Boolean doInBackground(String... args){ ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnected()) { try { URL url = new URL("https://www.google.ru/"); HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); urlc.setConnectTimeout(3000); urlc.connect(); if(urlc.getResponseCode() == 200){ return true; } }catch(MalformedURLException e1){ e1.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } } return false; } @Override protected void onPostExecute(Boolean th){ if(th == true){ nDialog.dismiss(); new Process().execute(); } else{ nDialog.dismiss(); Context context = getApplicationContext(); ErrorMsg.setText(""); } } }

вторник, 24 декабря 2019 г.

Progressbar в endlessList

#android #progress_bar


Есть бесконечный список, в котором подгружаю n-oe количество элементов после того
как пролистал до самого низа. Необходимо во время этой подгрузки отображать progressBar
в самом низу. Раньше использовал footerView, состоящего из progressBar, просто скрывал
и отображал его когда было необходимо. Но теперь я использую не listView, а recyclerView,
в который, увы, нельзя стандартными способами вставить header или footer.. Погуглив,
нашел пару библиотек, которые используют свой кастомный адаптер, вместо  RecyclerView.Adapter.
Так не хочется перелопачивать всё в проекте и прикручивать эту "эболу". Может кто сталкивался
с такой проблемой?
    


Ответы

Ответ 1



RecyclerView стал очень удобным в кастомизации, это как Lada, большое поле для фантазий, после выхода с конвейера =) Я недавно также у себя задавался вопросом, как сделать бесконечный список, в итоге сделал так С начала переопределил метод @Override public int getItemViewType(int position) { return isFooter(position) ? TYPE_FOOTER : TYPE_ITEM; } где константы: public static final int TYPE_ITEM = 0; public static final int TYPE_FOOTER = 1; public boolean isFooter(int position) { return mIsFooterEnabled && getItemCount() == position + (mIsFooterEnabled ? 1 : 0); } так как футер не входит в общий массив то дополним метод @Override public int getItemCount() { return mCatalogData != null ? mCatalogData.size() + (mIsFooterEnabled ? 1 : 0) : 0; } футер включаем или выключаем в случае если адаптер реюзаем ну или конец списка. private boolean mIsFooterEnabled; public void setFooterEnabled(boolean isFooterEnabled) { mIsFooterEnabled = isFooterEnabled; } Вот так выглядят Холдеры public static class ProductViewHolder extends RecyclerView.ViewHolder { ProductViewHolder(View itemView) { super(itemView); } } public static class FooterViewHolder extends RecyclerView.ViewHolder { FooterViewHolder(View itemView) { super(itemView); } } И соответственно метод onBindViewHolder @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) { if (holder instanceof ProductViewHolder) { ProductViewHolder productViewHolder = (ProductViewHolder) holder; } else { } } ну а в этом методе ставим нужные вью. @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) { if (type == TYPE_ITEM) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.catalog_list_item, viewGroup, false); return new ProductViewHolder(v); } else { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.catalog_list_footer, viewGroup, false); return new FooterViewHolder(v); } } что написано в catalog_list_item кидать не буду, излишне, а в catalog_list_footer просто прогресс бар. UPD Подгрузку начинаю делать, когда покажется вью на экране с позицией getItemCount()-10. mGridView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { int position = ((GridLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition(); int updatePosition = recyclerView.getAdapter().getItemCount() - 10; if (position >= updatePosition) { loadNewItems(); } } }); а данные вставляю вот так (Метод внутри адпатера) public void setData(List data) { if (mCatalogData == null) { mCatalogData = new ArrayList<>(); } mCatalogData.addAll(data); notifyItemInserted(getItemCount() - data.size()); }

Ответ 2



Если кому интересно будет, то я сделал таким образом: 1) В разметку с RecyclerView добавил progressBar 2) Далее во фрагменте, к recyclerView вешаю слушатель onScrollListener в котором смотрю, когда необходимо грузить элементы, то показываю свой progressBar if (loading) { if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) { pageNumber++; progressBar.setVisibility(View.VISIBLE); loadList(); loading = false; } } 3) В своём методе loadList() , после загрузки элементов и обновлении адаптера, присваиваю значение loading = true и progressBar.setVisibility(View.GONE). Единственное что остается сделать, это плавное появление progressBara снизу.

среда, 18 декабря 2019 г.

Как можно сделать ProgressBar с непрерывно движущейся картинкой?

#java #android #progress_bar


Как можно сделать ProgressBar, чтобы Image (картинка) непрерывно двигалась слева
направо, постепенно исчезая справа и появляясь слева?


    


Ответы

Ответ 1



Я вижу 2 пути: Использовать 2 картинки которые ты двигаешь одновременно а потом правую картинку перемещаешь влево в нужный момент. Конечно же, скрывая то, что видеть пользователь не должен. Использовать эфект оффсета(имеется ввиду эфект оффсет из стандартного набора фотошопа). То есть: Ты берешь самый правый столбец пикселей и переносишь ее на первый столбец(сдвигая другие вправо). Этот вариант, конечно же, лучше. Детали реализации гугли сам :)

вторник, 17 декабря 2019 г.

Круглый ProgressBar с 4 цветами (неплавный градиент)

#java #android #progress_bar #градиент




Update: залил новый скриншот, от 0 до 165 у нас круг закрашен, прогресс равен ~ 45%,
остальная часть тусклыми цветами

Есть ли возможность сделать progressbar с 4 цветами? По сути это градиент, но вот
только у тэга gradient нет параметров, позволяющих сделать строго разграниченные цвета
(знаю, что в api 24 такое вроде можно сделать, но мне нужно с api 15 и выше). Для прогресса
использую shape ring:


    
        
    



Заранее спасибо.
    


Ответы

Ответ 1



Путаетесь в терминологии - это раздражает многих, но не меня :-) (Просьбы о не плавном градиенте равнозначны мольбам о квадрате но без углов) Видимо вам нужны не градиенты а круговые диаграммы ну а дальше берите любую за основу и изменяйте в нужном вам направлении; присмотритесь например к MPAndroidChart, как вам верно подсказал @pavlofff в комментарии.

пятница, 13 декабря 2019 г.

Немигающий progressBar с возможностью задать текст внутри

#c_sharp #winforms #progress_bar #компоненты


Иногда нужно иметь прогрессбар с текстом внутри, а нейтивный прогрессбар не имеет
возможности выдавать текст внутри даного компонента.
Как реализовать?

В интернете всюду решения которые или с рамкой вокруг текста (тупо лейбл на прогрессбар
налеплен) или кастомные компоненты, которые банально мигают во время работы.
    


Ответы

Ответ 1



Т.к. всюду встречал только мигающие (blinking/flickering) решения, то решился написать свой собственный компонент -- TextProgressBar и поделится с общественностью. Соурс код можно найти здесь: https://github.com/ukushu/TextProgressBar Примеры: Особенности кода, которые нужно иметь ввиду тому, кто решится повторить "подвиг": Отсутствие мигания кастомного компонента можно достигнуть при помощи кода, оторый отключает "лишние" стили оригинального компонента SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); на стадии инициализации компонента. Так же можно столкнутся с проблемами обновления настроек заданных через VisualStudio. Для того что бы это обойти, нужно вызывать при изменении проблемных property: Invalidate(); что бы вижуалка перерисовала заново компонент. И так же не нужно допускать ошибку которую я сначала допустил при написании: не забываем что многие из классов для отрисовки элементов (да и сам контрол) являются дочерними от IDispousable, а, значит, должны вызывать .Dispose как только будут не нужны. Для распихивания пропертей по категориям в вижуалке нужно подписывать их следующим образом [Category("Additional Options")] //обьявление самой проперти Все остальное - просто логика отрисовки и реализации вашего кастомного компонента.

Ответ 2



Так уж вышло что заодно и WPF начал осваивать... Мало ли, может кому пригодится: Value/Maximum Результат: То же самое, но с процентом прогресса:

Круглый прогресс-бар с эффектом движения воды

#javascript #canvas #progress_bar #webgl


Кто знает как можно реализовать такой круглый прогресс-бар с эффектом воды как в
центральной части этого сайта https://asmobius.co.jp/ 


    


Ответы

Ответ 1



Подобные эффекты возможно сделать использовав фрагментный шейдер, в котором вычисляется каждый пиксель, в зависимости от положения слайдера. Здесь наблюдается 2 слоя: Один - 2 картинки одна поверх другой, между которыми происходит переход при помощи прозрачности картинки и сдвиг в противоположные стороны. Второй - кольцо, внутри которого так же находятся обе картинки, с границей, определяемой значением слайдера + искажение текстурных координат, для имитации эффекта воды. Для реализации я взял и скретил свои же старые ответы: эффект воды и огненное кольцо let pid, timeLocarion, valueLocation, v = Math.PI, value = Math.PI, gl = canvas.getContext('webgl'); loadTexture(0, "https://picsum.photos/id/88/400/400") loadTexture(1, "https://picsum.photos/id/77/400/400") addEventListener('wheel', s => { value = value - Math.sign(s.deltaY)*0.1; }) pid = gl.createProgram(); shader(`attribute vec2 c;void main(void){gl_Position=vec4(c,0.,1.);}`,gl.VERTEX_SHADER); shader(` precision lowp float; uniform vec2 size; // размер стороны квадрата этого беспредела uniform float time; // время uniform float val; // значение слайдера, от минус пи до пи uniform sampler2D tex1; // первая текстура uniform sampler2D tex2; // вторая ткестура // эффект воды vec2 waterEffect(vec2 uv) { float s = 0.; vec2 p = uv; for (int i = 0; i < 5; i++) { vec2 adjc = p; float theta = 2. * 3.1415 / 11.*float(i); adjc.x += cos(theta)*time*.1 + time * .03; adjc.y -= sin(theta)*time*.1 - time * .07; float a = adjc.x*cos(theta) - adjc.y*sin(theta); s += cos(a*15.) * 3.1415; } return p += sin(s)*.01; } void main(void) { // текстурные координаты vec2 uv = gl_FragCoord.xy / size.xy; // сдвигаем текстурные координаты, чтобы отсчет начинался от центра экрана vec2 c = uv - .5; // делаем из прямоугольника квадрат, чтобы был круг а не эллипс c.x *= size.x/size.y; // если фрагмент вне кольца if (abs(sqrt(dot(c, c)) - .4) > .05) { // смешиваем 2 текстуры в пропорциях в зависимости от положения слайдера float t = val/6.28 + .5; gl_FragColor = texture2D(tex1, vec2(uv.x + t*.1, uv.y))*t + texture2D(tex2, vec2(uv.x - t*.1, uv.y))*(1.-t); } else { // само кольцо vec2 water = waterEffect(uv); // тут небольшой хак с арктангенсом, обратите внимание на порядок следования /// аргументов, у нормального арктангенса первым аргументом идет y а вторым x, // перемена мест аргументов меняет местами оси системы координат - теперь //граница на кольце не слева а сверху if (atan(c.x, -c.y) > val) //справа или слева от границы ? gl_FragColor = texture2D(tex1, water); else gl_FragColor = texture2D(tex2, water); } } `, gl.FRAGMENT_SHADER); gl.linkProgram(pid); gl.useProgram(pid); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,3,-1,-1,3,-1]), gl.STATIC_DRAW); let al = gl.getAttribLocation(pid, "c"); gl.vertexAttribPointer(al, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(al); timeLocation = gl.getUniformLocation(pid, 'time'); valueLocation = gl.getUniformLocation(pid, 'val'); let sizeLocation = gl.getUniformLocation(pid, 'size'); gl.uniform2f(sizeLocation, gl.drawingBufferWidth, gl.drawingBufferHeight) gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); requestAnimationFrame(draw) function loadTexture(i, url) { let loader = new Image(); loader.crossOrigin = "anonymous"; loader.src = url; loader.onload = function() { let texture = gl.createTexture(); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, loader); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.uniform1i(gl.getUniformLocation(pid, "tex"+i), i); gl.activeTexture(gl.TEXTURE1); } } function draw(t) { let speed = Math.max(0.0001, Math.abs(value-v)*0.1); if (v < value) v = Math.min(value, v+speed); if (v > value) v = Math.max(value, v-speed); let val = v; while (val < -Math.PI) val += Math.PI*2; while (val > Math.PI) val -= Math.PI*2; gl.clearColor(0, 0, 0, 0); gl.uniform1f(timeLocation, t / 1000); gl.uniform1f(valueLocation, val); gl.drawArrays(gl.TRIANGLES, 0, 3); requestAnimationFrame(draw) } function shader(src, type) { let sid = gl.createShader(type); gl.shaderSource(sid, src); gl.compileShader(sid); var message = gl.getShaderInfoLog(sid); gl.attachShader(pid, sid); if (message.length > 0) { console.log(src.split("\n").map((str, i) => ("" + (1 + i)) .padStart(4, "0") + ": " + str).join("\n")); throw message; } }

суббота, 7 декабря 2019 г.

Изогнутый Progress Bar c# WPF

#c_sharp #wpf #progress_bar


Ребят, подскажите как сделать полукруглый прогресс бар? С обычным вообще не возникает
проблем. Находил только больно уж сложные, круглые примеры 
    


Ответы

Ответ 1



Просто тут и не будет, придется помудрить с геометрией. Ну что ж, давайте создадим UserControl, я назвал его MyProgress. Рисовать будем с помощью Path. Контрол будет состоять из двух Path - закрашенного и незакрашенного (закрашенного другим цветом). Для упрощения расчетов я взял эллипс с радиусами 100 и центром в точке (100,100). Нам нужно нарисовать 2 луча из центра и дугу: Точку я рассчитал для варианта 75% заполненности, вот что уже получается: Теперь из этого сектора нужно вырезать круг меньшего диаметра, сделаем это с помощью CombinedGeometry в режиме Exclude: Теперь аналогично рисуем вторую часть другим цветом: С разметкой пока всё, останется только привязать координаты рассчитанной точки в ArcSegment. Займемся кодом контрола: Свойство зависимости Value: public static DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(MyProgress), new FrameworkPropertyMetadata(OnValueChanged)); Вспомогательное свойство зависимости с координатами точки дуги: protected static DependencyProperty AuxiliaryPointProperty = DependencyProperty.Register("AuxiliaryPoint", typeof(Point), typeof(MyProgress)); Стандартные оболочки для этих свойств: public double Value { get => (double)GetValue(ValueProperty); set => SetValue(ValueProperty, value); } protected Point AuxiliaryPoint { get => (Point)GetValue(AuxiliaryPointProperty); set => SetValue(AuxiliaryPointProperty, value); } Ну и, наконец, метод, который будет пересчитывать координаты точки при смене Value: static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var myProgress = (MyProgress)d; var value = (double)e.NewValue; var angle = Math.PI * value / 100; var x = 100 - 100 * Math.Cos(angle); var y = 100 - 100 * Math.Sin(angle); myProgress.AuxiliaryPoint = new Point(x, y); } Теперь в разметке привяжемся к рассчитанной точке: Point="{Binding ElementName=myProgress, Path=AuxiliaryPoint}" Это нужно сделать для обоих ArcSegment В разметке я дал имя контролу для упрощения кода привязки: Всё. Это уже минимально рабочий прогрессбар, который можно добавить в окно: Выглядит так: Имейте ввиду, чтобы сделать этот контрол более-менее универсальным, вам потребуется его еще доработать, например, вынести в свойства зависимости цвета дуг и фона, минимальное и максимальное значение прогрессбара, диаметр внешнего и внутреннего круга и т.д. Привожу код контрола полностью, MyProgress.xaml: MyProgress.xaml.cs: using System; using System.Windows; using System.Windows.Controls; namespace WpfProgress { public partial class MyProgress : UserControl { public MyProgress() { InitializeComponent(); } public static DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(MyProgress), new FrameworkPropertyMetadata(OnValueChanged)); protected static DependencyProperty AuxiliaryPointProperty = DependencyProperty.Register("AuxiliaryPoint", typeof(Point), typeof(MyProgress)); static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var myProgress = (MyProgress)d; var value = (double)e.NewValue; var angle = Math.PI * value / 100; var x = 100 - 100 * Math.Cos(angle); var y = 100 - 100 * Math.Sin(angle); myProgress.AuxiliaryPoint = new Point(x, y); } public double Value { get => (double)GetValue(ValueProperty); set => SetValue(ValueProperty, value); } protected Point AuxiliaryPoint { get => (Point)GetValue(AuxiliaryPointProperty); set => SetValue(AuxiliaryPointProperty, value); } } } Раз UserControl несемантично, я сделал стиль (благодаря помощи @VladD) для ProgressBar. Потом решил добавить возможность редактирования внутреннего радиуса из разметки. Но аттачед проперти, меняющее поведение контрола, тоже несемантично, поэтому в итоге остановился на Custom Control, наследованном от ProgressBar. Идея используется та же, что описана в решении выше, но теперь контрол доработан полностью (наверное), поэтому разметка усложнилась из-за кучи привязок, а также из-за реализованного режима Indeterminate. Для тех, кто хочет создать такой контрол - добавьте в проект Add - New Item - Custom Control WPF, я назвал его SemicircleProgressBar, код самого контрола предельно прост - добавлено одно свойство зависимости: public class SemicircleProgressBar : ProgressBar { static SemicircleProgressBar() { DefaultStyleKeyProperty.OverrideMetadata(typeof(SemicircleProgressBar), new FrameworkPropertyMetadata(typeof(SemicircleProgressBar))); } public static DependencyProperty CuttingFactorProperty = DependencyProperty.Register(nameof(CuttingFactor), typeof(double), typeof(SemicircleProgressBar), new FrameworkPropertyMetadata(0.8)); public double CuttingFactor { get => (double)GetValue(CuttingFactorProperty); set => SetValue(CuttingFactorProperty, value); } } В появившемся файле Generic.xaml в папке Themes в корне проекта разметим стиль нового контрола: Конвертеры. ValueToAuxiliaryPointConverter: class ValueToAuxiliaryPointConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Contains(DependencyProperty.UnsetValue)) return DependencyProperty.UnsetValue; var v = (double)values[0]; var min = (double)values[1]; var max = (double)values[2]; var r = (double)values[3]; var ratio = (v - min) / (max - min); var angle = Math.PI * ratio; var x = 1 - r * Math.Cos(angle); var y = 1 - r * Math.Sin(angle); return new Point(x, y); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } RadiusToSizeConverter: class RadiusToSizeConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var r = (double)value; return new Size(r, r); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } Код для демонстрации: Использована информация из этого ответа

вторник, 16 июля 2019 г.

Можно ли на ProgressBar'е что нибудь написать?

Есть такая задачка: ProgressBar показывает линию загрузки(статичная) и сверху него же написать его значение?


Ответ

Наследуй ProgressBar, переопределяй метод onDraw() и пиши/рисуй все что душе угодно. пример

понедельник, 15 июля 2019 г.

Progressbar выводит только background изображение

Подскажите в чем ошибка при стилизации progressBarStyleHorizontal? Подменил у ProgressBar свойство progressDrawable, но выставление значений для контрола к видимым изменениям не приводит. Показывается только пустой ProgressBar.
Вот часть хмл из layout-а:

вот кастомный drawable:

изображения - nine-patch png: в коде значения:
mFullProgress.setMax(100); mFullProgress.setProgress(70);
стиль приложения:

скриншот пустого прогрессбара:

Update (результат правок):
В приницпе похоже на правду (см ответ), но результат странный, вот скриншот
Update (добавлен clip элемент в drawable): После добавления clip для progress

контрол реагирует на изменение значений (progress и max):
Update (рабочее решение): Проблема была в отсутсвии у nine-patch background изображения отметок об области контента. При рендеринге layer-list все слои после первого сжимались в 0 (при некоторых размерах контрола можно было видеть тонкую полоску). поправленный бекграунд

верстка

скриншот


Ответ

Проблема, возможно, в конфликте стиля виджета и присвоенного drawable
Попробуйте определить собственную тему для него как описано тут
В стилях: res/values/styles.xml

И назначаем наш кастомный стиль:

Круглый progress bar с анимацией

Пытаюсь сделать круглый progress bar. Идея такая, что progress - служит фоном, а secondaryProgress отображает само значение.
Код из layout:

Код progressbarstyle.xml:


На превью отображается верно, но если запустить на телефоне, то всегда показывает 100%. В чем ошибка? И как добавить анимацию при изменении значения secondaryProgress?


Ответ

Согласно en-SO можно заменить содержимое вашего progressbarstyle.xml на вот это и оно будет работать:

Также, по ссылке помянуто как это заставить работать на API<21 и как анимировать.

четверг, 11 июля 2019 г.

как через js jQuery сделать индикаторы, которые правильно показывали б температуру и менялись в зависимости от условия


Я хочу создать эти индикаторы голубые на css И вообще, как сделать так чтобы они работали в зависимости от того какая погода? Чтобы менялся размер индикатора. Это json ? Помогите пожалуйста


Ответ

Если особо не напрягаться приблизительный концепт:
$('.indicator').each(function() { var currentHeight = $(this).height(); var newHeight = $(this).data('current'); //здесь происходит просчет заданной цифры температуры var totalHeight = (currentHeight + newHeight) * 10; //Умножение добавляем для красоты полоски $(this).css('height', totalHeight); $(this).append('

').find(".curren-temperature").text(totalHeight / 10) //при выводе температуры убираем умножение, которое добавляло красоту. }); * { box-sizing: border-box; } html, body { height: 100%; } .wrapper { height: 100%; max-width: 800px; margin: auto; background: #000217; } .indicator-list { display: flex; justify-content: space-around; list-style: none; padding: 0; margin: auto; color: #fff; } .indicator { background: #00BFF5; width: 30px; height: 0; margin: 10px; position: relative; border-radius: 20px; } .curren-temperature { position: absolute; bottom: -20px; width: 50px; }

вторник, 2 апреля 2019 г.

Как сделать slick слайдер с горизонтальным прогресс баром?

Нужно сделать таймер как здесь http://www.apple.com/
Слайдер сделан с помощью slick.js, но к сожалению в плагине нет такого таймера. Можно ли было Speed передавать прогресс-бару?
$(document).ready(function () { $('.slider').slick({ infinite: true, autoplay:true, dots: true, arrows: false, autoplaySpeed: 3000, slidesToShow: 1, slidesToScroll: 1 }); }) .slider .slick-dots { padding: 0; } .slider .slick-dots li { position: relative; display: inline-block; width: 19%; height: 15px; margin: 0 2px 0 0; padding: 0; cursor: pointer; background: #ccbdb6; transition: width 5s ease-out 0s; } .slider .slick-dots li:last-child { margin-right: 0; } .slider .slick-dots li:hover, .slider .slick-dots li.slick-active { background: #a08a7f; } .slider .slick-dots li button { display: none !important; }

1

2

3

4

5



Ответ

добавлено css
$(document).ready(function() { $('.slider').slick({ infinite: true, autoplay: true, dots: true, arrows: false, autoplaySpeed: 3000, slidesToShow: 1, slidesToScroll: 1 }); }) .slider .slick-dots{ padding:0; } .slider .slick-dots li{ position:relative; display:inline-block; width:19%; height:15px; margin:0 2px 0 0; padding:0; cursor:pointer; background-color:#ccbdb6; background-size:100% 100%; background-image:-webkit-gradient(linear, left, right, color-stop(1, rgb(16,56,16)), color-stop(1, transparent)); background-image:-o-linear-gradient(left, rgb(16,56,16) 100%, transparent); background-image:-moz-linear-gradient(left, rgb(16,56,16) 100%, transparent); background-image:-webkit-linear-gradient(left, rgb(16,56,16) 100%, transparent); background-image:linear-gradient(to right,rgb(16,56,16) 100%,transparent 100%); background-repeat:no-repeat; } .slider .slick-dots li:last-child{ margin-right:0; } .slider .slick-dots li:hover,.slider .slick-dots li.slick-active{ background-color:#a08a7f; } .slider .slick-dots li button{ display: none !important; } .slider .slick-dots li.slick-active~li{ background-size:0% 0%; } .slider .slick-dots li.slick-active{ -webkit-animation:right 3s ease-in-out forwards; -moz-animation:right 3s ease-in-out forwards; -o-animation:right 3s ease-in-out forwards; animation:right 3s ease-in-out forwards; } @keyframes right{ 0%{ background-size:0% 100%; } 100%{ background-size:100% 100%; } }

1

2

3

4

5


понедельник, 28 января 2019 г.

Изогнутый Progress Bar c# WPF

Ребят, подскажите как сделать полукруглый прогресс бар? С обычным вообще не возникает проблем. Находил только больно уж сложные, круглые примеры


Ответ

Просто тут и не будет, придется помудрить с геометрией.
Ну что ж, давайте создадим UserControl, я назвал его MyProgress
Рисовать будем с помощью Path. Контрол будет состоять из двух Path - закрашенного и незакрашенного (закрашенного другим цветом). Для упрощения расчетов я взял эллипс с радиусами 100 и центром в точке (100,100).
Нам нужно нарисовать 2 луча из центра и дугу:

Точку я рассчитал для варианта 75% заполненности, вот что уже получается:
Теперь из этого сектора нужно вырезать круг меньшего диаметра, сделаем это с помощью CombinedGeometry в режиме Exclude


Теперь аналогично рисуем вторую часть другим цветом:


С разметкой пока всё, останется только привязать координаты рассчитанной точки в ArcSegment
Займемся кодом контрола:
Свойство зависимости Value
public static DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(MyProgress), new FrameworkPropertyMetadata(OnValueChanged));
Вспомогательное свойство зависимости с координатами точки дуги:
protected static DependencyProperty AuxiliaryPointProperty = DependencyProperty.Register("AuxiliaryPoint", typeof(Point), typeof(MyProgress));
Стандартные оболочки для этих свойств:
public double Value { get => (double)GetValue(ValueProperty); set => SetValue(ValueProperty, value); }
protected Point AuxiliaryPoint { get => (Point)GetValue(AuxiliaryPointProperty); set => SetValue(AuxiliaryPointProperty, value); }
Ну и, наконец, метод, который будет пересчитывать координаты точки при смене Value
static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var myProgress = (MyProgress)d; var value = (double)e.NewValue; var angle = Math.PI * value / 100; var x = 100 - 100 * Math.Cos(angle); var y = 100 - 100 * Math.Sin(angle); myProgress.AuxiliaryPoint = new Point(x, y); }
Теперь в разметке привяжемся к рассчитанной точке:
Point="{Binding ElementName=myProgress, Path=AuxiliaryPoint}"
Это нужно сделать для обоих ArcSegment
В разметке я дал имя контролу для упрощения кода привязки:

Всё. Это уже минимально рабочий прогрессбар, который можно добавить в окно:

Выглядит так:

Имейте ввиду, чтобы сделать этот контрол более-менее универсальным, вам потребуется его еще доработать, например, вынести в свойства зависимости цвета дуг и фона, минимальное и максимальное значение прогрессбара, диаметр внешнего и внутреннего круга и т.д.
Привожу код контрола полностью, MyProgress.xaml

MyProgress.xaml.cs
using System; using System.Windows; using System.Windows.Controls;
namespace WpfProgress { public partial class MyProgress : UserControl { public MyProgress() { InitializeComponent(); }
public static DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(MyProgress), new FrameworkPropertyMetadata(OnValueChanged)); protected static DependencyProperty AuxiliaryPointProperty = DependencyProperty.Register("AuxiliaryPoint", typeof(Point), typeof(MyProgress));
static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var myProgress = (MyProgress)d; var value = (double)e.NewValue; var angle = Math.PI * value / 100; var x = 100 - 100 * Math.Cos(angle); var y = 100 - 100 * Math.Sin(angle); myProgress.AuxiliaryPoint = new Point(x, y); }
public double Value { get => (double)GetValue(ValueProperty); set => SetValue(ValueProperty, value); }
protected Point AuxiliaryPoint { get => (Point)GetValue(AuxiliaryPointProperty); set => SetValue(AuxiliaryPointProperty, value); } } }

Раз UserControl несемантично, я сделал стиль (благодаря помощи @VladD) для ProgressBar. Потом решил добавить возможность редактирования внутреннего радиуса из разметки. Но аттачед проперти, меняющее поведение контрола, тоже несемантично, поэтому в итоге остановился на Custom Control, наследованном от ProgressBar
Идея используется та же, что описана в решении выше, но теперь контрол доработан полностью (наверное), поэтому разметка усложнилась из-за кучи привязок, а также из-за реализованного режима Indeterminate
Для тех, кто хочет создать такой контрол - добавьте в проект Add - New Item - Custom Control WPF, я назвал его SemicircleProgressBar, код самого контрола предельно прост - добавлено одно свойство зависимости:
public class SemicircleProgressBar : ProgressBar { static SemicircleProgressBar() { DefaultStyleKeyProperty.OverrideMetadata(typeof(SemicircleProgressBar), new FrameworkPropertyMetadata(typeof(SemicircleProgressBar))); }
public static DependencyProperty CuttingFactorProperty = DependencyProperty.Register(nameof(CuttingFactor), typeof(double), typeof(SemicircleProgressBar), new FrameworkPropertyMetadata(0.8));
public double CuttingFactor { get => (double)GetValue(CuttingFactorProperty); set => SetValue(CuttingFactorProperty, value); } }
В появившемся файле Generic.xaml в папке Themes в корне проекта разметим стиль нового контрола:


Конвертеры. ValueToAuxiliaryPointConverter
class ValueToAuxiliaryPointConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Contains(DependencyProperty.UnsetValue)) return DependencyProperty.UnsetValue; var v = (double)values[0]; var min = (double)values[1]; var max = (double)values[2]; var r = (double)values[3]; var ratio = (v - min) / (max - min); var angle = Math.PI * ratio; var x = 1 - r * Math.Cos(angle); var y = 1 - r * Math.Sin(angle); return new Point(x, y); }
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
RadiusToSizeConverter
class RadiusToSizeConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var r = (double)value; return new Size(r, r); }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
Код для демонстрации:






Использована информация из этого ответа

среда, 12 декабря 2018 г.

Progress bar первоначальной загрузки

Подскажите, с помощью чего можно сделать такой прогресс бар.


Ответ

Это стандартный ProgressDialog. Пример:
ProgressDialog progressDialog = new ProgressDialog(this); progressDialog.setMessage("Идет поиск рейсов"); progressDialog.show();
Для отмены:
progressDialog.dismiss();
Можете обвешать чем необходимо:
.setCancelable(false); //не закрывается по тапу вокруг .setTitle("Title"); //Заголовок
И много другого, подробно в официальной документации

вторник, 27 ноября 2018 г.

Progressbar в endlessList

Есть бесконечный список, в котором подгружаю n-oe количество элементов после того как пролистал до самого низа. Необходимо во время этой подгрузки отображать progressBar в самом низу. Раньше использовал footerView, состоящего из progressBar, просто скрывал и отображал его когда было необходимо. Но теперь я использую не listView, а recyclerView, в который, увы, нельзя стандартными способами вставить header или footer.. Погуглив, нашел пару библиотек, которые используют свой кастомный адаптер, вместо RecyclerView.Adapter. Так не хочется перелопачивать всё в проекте и прикручивать эту "эболу". Может кто сталкивался с такой проблемой?


Ответ

RecyclerView стал очень удобным в кастомизации, это как Lada, большое поле для фантазий, после выхода с конвейера =)
Я недавно также у себя задавался вопросом, как сделать бесконечный список, в итоге сделал так
С начала переопределил метод
@Override public int getItemViewType(int position) { return isFooter(position) ? TYPE_FOOTER : TYPE_ITEM; }
где константы:
public static final int TYPE_ITEM = 0; public static final int TYPE_FOOTER = 1;
public boolean isFooter(int position) { return mIsFooterEnabled && getItemCount() == position + (mIsFooterEnabled ? 1 : 0); }
так как футер не входит в общий массив то дополним метод
@Override public int getItemCount() { return mCatalogData != null ? mCatalogData.size() + (mIsFooterEnabled ? 1 : 0) : 0; }
футер включаем или выключаем в случае если адаптер реюзаем ну или конец списка.
private boolean mIsFooterEnabled; public void setFooterEnabled(boolean isFooterEnabled) { mIsFooterEnabled = isFooterEnabled;
}
Вот так выглядят Холдеры
public static class ProductViewHolder extends RecyclerView.ViewHolder {
ProductViewHolder(View itemView) { super(itemView); } }
public static class FooterViewHolder extends RecyclerView.ViewHolder {
FooterViewHolder(View itemView) { super(itemView);
} }
И соответственно метод onBindViewHolder
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) { if (holder instanceof ProductViewHolder) { ProductViewHolder productViewHolder = (ProductViewHolder) holder;
} else {
} }
ну а в этом методе ставим нужные вью.
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) { if (type == TYPE_ITEM) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.catalog_list_item, viewGroup, false); return new ProductViewHolder(v); } else { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.catalog_list_footer, viewGroup, false); return new FooterViewHolder(v); } }
что написано в catalog_list_item кидать не буду, излишне, а в catalog_list_footer просто прогресс бар.
UPD Подгрузку начинаю делать, когда покажется вью на экране с позицией getItemCount()-10.
mGridView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { int position = ((GridLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition(); int updatePosition = recyclerView.getAdapter().getItemCount() - 10; if (position >= updatePosition) {
loadNewItems();
} } });
а данные вставляю вот так (Метод внутри адпатера)
public void setData(List data) { if (mCatalogData == null) { mCatalogData = new ArrayList<>();
} mCatalogData.addAll(data); notifyItemInserted(getItemCount() - data.size()); }

понедельник, 29 октября 2018 г.

Згрузка и отображение процесса

Использую этот код чтобы загрузить картинки
-(IBAction) downloadButton:(id)sender {
if(_downloadTask == nil){
_url1 =[NSURL URLWithString:@"someUrl"]; _url2 =[NSURL URLWithString:@"someUrl"]; _downloadTask = [_session downloadTaskWithURL:_url1]; _downloadTask1 = [_session downloadTaskWithURL:_url2]; [_downloadTask resume]; [_downloadTask1 resume];
} else [_downloadTask resume]; [_downloadView removeFromSuperview]; [_downloadButton removeFromSuperview]; [_downloadButtonCancel removeFromSuperview];
} }
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
_paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); _documentsDirectory1 = [_paths1 objectAtIndex:0]; _filePath1 = [_documentsDirectory1 stringByAppendingPathComponent:@"1.png"]; _fileExists1 = [[NSFileManager defaultManager] fileExistsAtPath:_filePath1 isDirectory:false];
_paths2 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); _documentsDirectory2 = [_paths2 objectAtIndex:0]; _filePath2 = [_documentsDirectory2 stringByAppendingPathComponent:@"2.png"]; _fileExists2 = [[NSFileManager defaultManager] fileExistsAtPath:_filePath2 isDirectory:false]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *urlData1 = [NSData dataWithContentsOfURL:_url1]; [urlData1 writeToFile:_filePath1 atomically:YES];
NSData *urlData2 = [NSData dataWithContentsOfURL:_url2]; [urlData2 writeToFile:_filePath2 atomically:YES]; });
И этот код для отображения хода загрузки в процентах
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite; { dispatch_async(dispatch_get_main_queue(), ^{
float progress = [[NSNumber numberWithInteger:totalBytesWritten] floatValue]; float total = [[NSNumber numberWithInteger:totalBytesExpectedToWrite] floatValue];
NSString *percentage = [NSString stringWithFormat:@"%.f%%", ((progress / total) * 100)];
NSLog(@"%.f%%", percentage);
if (!_label) {

_label = [[UILabel alloc] initWithFrame:CGRectMake(300, 130, 42, 19)];
_label.numberOfLines = 1; _label.baselineAdjustment = UIBaselineAdjustmentAlignBaselines; _label.adjustsFontSizeToFitWidth = YES; _label.minimumScaleFactor = 10.0f/12.0f; _label.clipsToBounds = YES; _label.backgroundColor = [UIColor clearColor]; _label.textColor = [UIColor whiteColor]; _label.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:_label];
}
_label.text = percentage;
Проблема в том, что label не отображает загрузку от 1% до 100%. а беспорядочно показывает разные цифры. Как это исправить?


Ответ

Так ты ведь два урла сразу грузишь, вот они оба одновременно свой прогресс и показывают. Нужно или грузить их по очереди, или по параметру downloadTask:(NSURLSessionDownloadTask *)downloadTask определять какой это таск и менять соответствующий label. Также можно вести один общий прогресс для двух урлов.