Mam FrameLayout, w którym mam 2 kontrolki: - widok niestandardowy, który rysuje obraz i tekst na nim - widok tekstu z tekstem
Chcę wyśrodkować oba w FrameLayout, ale nie mogę tego zrobić. Texview jest dobrze wyśrodkowany, mój niestandardowy widok pozostaje po lewej stronie, kiedy go pokazuję.
<FrameLayout android:id="@+id/CompassMap"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center">
<view class="com.MyView"
android:id="@+id/myView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:visibility="gone"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:text="CENTERED" />
</FrameLayout>
Dla Mathiasa nic nie robię w konstruktorze, to po prostu proste
public class MyMapView extends View {
private int xPos = 0;
private int yPos = 0;
private Bitmap trackMap;
private Matrix backgroundMatrix;
private Paint backgroundPaint;
private Bitmap position;
private Matrix positionMatrix;
private Paint positionPaint;
public MyMapView(Context context) {
super(context);
init(context, null);
}
public MyMapView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public MyMapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(final Context context, AttributeSet attrs) {
backgroundMatrix = new Matrix();
backgroundPaint = new Paint();
backgroundPaint.setFilterBitmap(true);
position = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.position);
positionMatrix = new Matrix();
positionPaint = new Paint();
positionPaint.setFilterBitmap(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
int width = getMeasuredWidth();
int height = getMeasuredHeight();
if (trackMap!=null)
{
Bitmap resizedBitmap = Bitmap.createScaledBitmap(trackMap, height, height, true);
canvas.drawBitmap(resizedBitmap, backgroundMatrix, backgroundPaint);
}
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(xPos-position.getWidth()/2, yPos-position.getHeight()/2);
canvas.drawBitmap(position, positionMatrix, positionPaint);
canvas.restore();
}
public void updatePosition(int xpos, int ypos, Bitmap trackImage)
{
xPos=xpos;
yPos=ypos;
trackMap = trackImage;
invalidate();
}
}
Odpowiedzi:
Sugerowałbym RelativeLayout zamiast FrameLayout.
Zakładając, że chcesz mieć TextView zawsze poniżej ImageView, użyłbym następującego układu.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerInParent="true" android:src="@drawable/icon" android:visibility="visible"/> <TextView android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_below="@id/imageview" android:gravity="center" android:text="@string/hello"/> </RelativeLayout>
Zwróć uwagę, że jeśli ustawisz
visibility
element na,gone
to przestrzeń, którą ten elementinvisible
zajmowałby, zniknie, podczas gdy gdy użyjesz zamiast tego miejsca, które zajmie, zostanie zachowane.Jeśli chcesz, aby TextView znajdował się na wierzchu ImageView, po prostu pomiń
android:layout_alignParentTop
lub ustaw go nafalse
i na TextView opuśćandroid:layout_below="@id/imageview"
atrybut. Lubię to.<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="false" android:layout_centerInParent="true" android:src="@drawable/icon" android:visibility="visible"/> <TextView android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center" android:text="@string/hello"/> </RelativeLayout>
Mam nadzieję, że właśnie tego szukałeś.
źródło
Możemy wyrównać widok do środka
FrameLayout
, ustawiająclayout_gravity
widok podrzędny.W XML:
android:layout_gravity="center"
W kodzie Java:
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.gravity = Gravity.CENTER;
Uwaga:
FrameLayout.LayoutParams
nie używaj innych istniejących LayoutParamsźródło
Po prostu wykonaj tę kolejność
Możesz wyśrodkować dowolną liczbę dzieci w
FrameLayout
.<FrameLayout > <child1 .... android:layout_gravity="center" ..... /> <Child2 .... android:layout_gravity="center" /> </FrameLayout>
Na przykład:
I skupia się CustomView i TextView na zasadzie
FrameLayout
tak<FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <com.airbnb.lottie.LottieAnimationView android:layout_width="180dp" android:layout_height="180dp" android:layout_gravity="center" app:lottie_fileName="red_scan.json" app:lottie_autoPlay="true" app:lottie_loop="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textColor="#ffffff" android:textSize="10dp" android:textStyle="bold" android:padding="10dp" android:text="Networks Available: 1\n click to see all" android:gravity="center" /> </FrameLayout>
źródło
FrameLayout
który zawiera jedenTextureView
i dwaSurfaceView
. Dzięki temu (isetZOrderOnTop(true);
na powierzchniach ostatecznie wycentrowałem nakładkęUstaw „center_horizontal” i „center_vertical” lub po prostu „środek” atrybutu layout_gravity widżetu
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MovieActivity" android:id="@+id/mainContainerMovie" > <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#3a3f51b5" /> <ProgressBar android:id="@+id/movieprogressbar" style="?android:attr/progressBarStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|center_horizontal" /> </FrameLayout>
źródło
Aby wyśrodkować widok we Framelayout, istnieje kilka dostępnych sztuczek. Najprostszy, którego użyłem w moim Webview i Progressbar (bardzo podobny do twojego układu dwóch obiektów), właśnie dodałem
android:layout_gravity="center"
Oto pełny kod XML na wypadek, gdyby ktoś inny potrzebował tego samego
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".WebviewPDFActivity" android:layout_gravity="center" > <WebView android:id="@+id/webView1" android:layout_width="match_parent" android:layout_height="match_parent" /> <ProgressBar android:id="@+id/progress_circular" android:layout_width="250dp" android:layout_height="250dp" android:visibility="visible" android:layout_gravity="center" /> </FrameLayout>
Oto mój wynik
źródło