#android
#Android
Вопрос:
У меня есть пользовательское представление………
package com.yasir.canvasTest;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.util.Log;
import android.view.View;
public class GraphView extends View {
private static final String TAG = "GraphView";
public static boolean BAR = true;
public static boolean LINE = false;
private Paint paint;
private float[] values;
private String[] horlabels;
private String[] verlabels;
private String title;
private boolean type;
public Canvas tmpCanvas = null;
public GraphView(Context context, float[] values, String title, String[] horlabels, String[] verlabels) {
super(context);
//setScrollContainer(true);
Log.v(TAG,"On GraphView==>");
paint = new Paint();
setWillNotDraw(false);
requestLayout();
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
Log.v(TAG,"<==On Draw");
/// drawing code here
invalidate();
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.v(TAG,"On onMeasure==>");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(
parentWidth * 2, parentHeight);
}
}
……………
Действие: onCreate
……………
setContentView(R.layout.horscroll);
HorizontalScrollView hsView = (HorizontalScrollView) findViewById(R.id.hzsv);
LinearLayout ll = (LinearLayout) findViewById(R.id.linearParent);
ll.removeAllViews();
// create custom view and add to laywout
GraphView graphView = new GraphView(this, values, "GraphViewDemo",horlabels, verlabels, GraphView.LINE);
hsView.requestLayout();
hsView.setWillNotDraw(false);
ll.requestLayout();
ll.setWillNotDraw(false);
ll.addView(graphView);
…………………
Xml
………………..
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
android:id="@ id/hzsv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:id="@ id/linearParent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"></LinearLayout>
</HorizontalScrollView>
………………
С уважением, Ясир Первез
Ответ №1:
Попробуйте проверить с помощью Hierarchy Viewer, что происходит. Я подозреваю, что ваше представление не отображается, потому что оно имеет ширину 0, и это может быть по двум причинам (одной или обеим):
- вы не устанавливаете ничего
LinearLayout.LayoutParams
в своем пользовательском представлении перед добавлением его в макет, и я не уверен, что значения по умолчанию относятся к типу «заполняющий родитель»; - ваш
onMeasure()
неполный, он также должен учитывать режим (UNSPECIFIED
,EXACTLY
,AT_MOST
), который также будет зависеть от параметров макета. Нет гарантии, чтоgetSize()
возвращает родительский размер, и, поскольку подразумевается фреймворк, вы даже не должны знать, произойдет ли это.
(предложение @slund, вероятно, тоже будет полезным)
Комментарии:
1. хороший момент в параметрах макета. Я понимаю, что я добавил layoutparams в свой тест, поэтому я вернулся и протестировал без этого. В любом случае меня просили измерить нулевую ширину. Это действительно озадачивает меня. Я даже помещаю scrollview в линейный макет с шириной «fill_parent» и ВСЕ равно получаю нулевое значение. Мне нужно разобраться в этом подробнее. FillViewport помогает в любом случае, но я просто пока не удовлетворен. Очевидно, что мне есть чему поучиться в scrollviews 🙂
2. @slund: в документах говорится, что
onMeasure()
это может вызываться несколько раз, даже с размерами 0-0, чтобы увидеть, какого размера хотел бы быть вид. Смотрите Вид , макет раздела.3. ОК. Возвращаюсь к чтению кода, и теперь я понимаю, что происходит. HorizontalScrollView переопределяет measureChild и measureChildWithMargins и принудительно присваивает ширине MeasureSpec значение MeasureSpec. НЕ УКАЗАНО. Если вы установите для FillViewport значение true, child.measure вызывается напрямую с помощью MeasureSpec.ТОЧНО и ширины окна просмотра. Таким образом, любое представление в HorizontalScrollView ДОЛЖНО обрабатывать MeasureSpec. НЕУКАЗАННЫЙ тип в их onMeasure и определяет их собственную ширину. Независимо от того, что вы вводите в XML для layout_width.
Ответ №2:
Ваш GraphView измеряется шириной 0 (ноль). Затем вы запрашиваете, чтобы для него было установлено значение 2 * width, которое по-прежнему равно нулю. Логика рисования оптимизирует не запрашивать представление нулевой ширины для рисования.
Вероятно, вы хотите попросить HorizontalScrollView заполнить всю ширину представления с помощью android:FillViewport=»true», т.Е.:
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@ id/hzsv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout
android:id="@ id/linearParent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</LinearLayout>
</HorizontalScrollView>
Также смотрите ответ @bigstones. Вам действительно нужно обрабатывать все типы MeasureSpec (НЕУКАЗАННЫЕ, AT_MOST, ТОЧНО). Установка FillViewport=»true» позволяет вызвать onMeasure с ТОЧНЫМ указанием типа и ширины окна просмотра.
Комментарии:
1. Спасибо всем за такую хорошую поддержку, это было очень полезно. моя проблема решена. и узнал кое-что о scrollviews