Cześć!
Jestem początkującym ( choć to i tak za dużo powiedziane ) jeżeli chodzi o Jave i pisanie aplikacji na androida, ale od czegoś trzeba zacząć. Chcę stworzyć pewną aplikację. Sama w sobie nie jest jakoś szczególnie trudna, ale najwięcej problemów sprawia mi layout. Potrzebuję wrzucić do aplikacji miernik/prędkościomierz taki jak/podobny do tego na obrazku (ten niebieski po lewej) . To co udało mi się zrobić to stworzenie tła w photoshopie razem z tą szarą linią na mierniku z dopisanymi obok prędkościami. Wygląda to identycznie, jakby prędkość wynosiła 0. Następnie w android studio chcę zrobić 2 customowe progress bary. Jeden okrągły, zaczynający się od pewnego kąta i kończący się na innym ( np. od 90 stopni do 250 stopni ), a drugi prosty. Chciałem ja ustawić obok siebie i wtedy miałbym identyczny kształt jak na rysunku. Jednak pojawił się problem. Ustawienie tego okrągłego paska idealnie równo z miarką na tle, jest całkiem trudne, to raz, natomiast dwa, to po zmianie rozmiaru ekranu z np. 4 cali do 6 cali, progress bar znajduje się w innym miejscu i już w ogóle nie pokrywa tła. Jedyne rozwiązanie jakie znalazłem to zaprogramowanie od początku własnego paska, z miarką, prędkościami i wypełnieniem, ale z tego co znalazłem to takie paski to nawet 1000 linii kodu. Mój najbardziej udany projekt w C++ miał jakieś 800-900 linijek.
Chciałbym się dowiedzieć, czy mogę to jakoś wykonać w miarę prostym rozwiązaniem. Dziękuję!
Nie da sie tego zrobic prostym rozwiazaniem. Natomiast jak juz sie sam przekonales robienie tego na podkladce jest zle
Ok. Postaram się wykonać to jakoś inaczej. Może znajdę coś na moje możliwości. Myślę, że temat jest do zamknięcia.
Pewnie już za późno ale wstawię. Nie trzeba tysiąca lini kodu. Może sie komuś przyda.
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
public static final String AKCJA = "akcja";
private static final int POCZATEK_WSKAZNIKA=90;
ImageView iw;
Paint mPaint,mPaintTxt;
Bitmap bmp;
Canvas canva;
Path mPathSzaraKreska,mPathPredkosc;
RectF mRectF;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//potrzebujemy uchwytu do naszego imageView
iw=(ImageView)findViewById(R.id.imageView);
// potrzebujemy painta gdzie okreslimy kolor
mPaint=new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.argb(255, 200, 200, 200));// to szary kolor
mPaint.setStyle(Paint.Style.STROKE);// linia
mPaint.setStrokeWidth(2);// grubosc lini
// paint dla textu
mPaintTxt=new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintTxt.setColor(Color.BLUE);
mPaintTxt.setFakeBoldText(true);
mPaintTxt.setTextSize(120);
mPathSzaraKreska=new Path();
mPathPredkosc=new Path();
// tworzymy pustą bitmape
bmp= Bitmap.createBitmap(600,600, Bitmap.Config.ARGB_8888);
// i canvas tej bitmapy zeby bylo po czym rysowac
canva=new Canvas(bmp);
// tworzymy tlo dla naszego wskaznika
canva.drawColor(Color.BLACK);
//potrzebujemy kwadratu w ktorym umiescimy łuk i prosta
mRectF=new RectF(); mRectF.left=50; mRectF.top=50; mRectF.right=550; mRectF.bottom=550;
// potrzebujemy na stale szara kreske wskaznika czyli pol okrag i prosta
mPathSzaraKreska.addArc(mRectF, POCZATEK_WSKAZNIKA, 180);
mPathSzaraKreska.lineTo(mRectF.width(),mRectF.top);
// koniec przygotowan
// reszta w metodzie
pokarzPredkosc( 0);
}
private void pokarzPredkosc(float predkosc){
// zamazujemy obecne wskazanie
canva.drawColor(Color.BLACK);
//rysujemy szara kreske
mPaint.setColor(Color.argb(255, 200, 200, 200));
mPaint.setStrokeWidth(2);
canva.drawPath(mPathSzaraKreska, mPaint);
// zerujemy poprzednia predkosc
mPathPredkosc.reset();
//a teraz ustalamy nowa predkosc
// dwie cwiartki po 90 stopni daje 180 a potem prosta kreska
// koniec łuku przypada na środek bitmapy
// predkosc minus 180 to reszta ktora ma byc prosta kreska
if ((predkosc > 180)&&(predkosc <= mRectF.width())){
mPathPredkosc.addArc(mRectF,POCZATEK_WSKAZNIKA,180);
mPathPredkosc.lineTo((canva.getWidth()/2)+(predkosc-180), mRectF.top);
}
if (predkosc <= 180){
mPathPredkosc.addArc(mRectF,POCZATEK_WSKAZNIKA,predkosc);
}
//zostaje wpisac kolor i szerokosc paska predkosci
mPaint.setColor(Color.BLUE);
mPaint.setStrokeWidth(40);
// i narysowac
canva.drawPath(mPathPredkosc,mPaint);
//jeszcze predkosc liczbowo pozycje ustalilem na oko :)
canva.drawText("" + (int)predkosc,200,330,mPaintTxt);
iw.setImageBitmap(bmp);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
To tylko przykład a nie konkretny kod. Nie problem dopasować do konkretnego wyświetlacza. Czarne tło plus szara kreska jest odmalowywana za każdym razem co wynika z kodu, a później jest malowany pasek prędkości który tez można zmienić na ciekawszy. Wielkość komponentu też można zwiększać, zmniejszać.
Wcale nie jest za późno, zajmowałem się innymi kwestami aplikacji. Dziękuję za kod, jak znajdę wolną chwilę to spróbuję coś z nim zrobić.
@Edit
Sądząc jednak po kodzie i komentarzu wojtka, wydaje mi się, że to będzie kiepskie rozwiązanie, gdyż przy innym rozmiarze telefonu, cały layout może się posypać.
ImageView jest typowym komponentem więc co się ma posypać, ale zrobisz jak chcesz jeśli jest coś nie zrozumiałego w kodzie to pytaj.