Пользовательский вид прокрутки выдает Android

1

Я разрабатываю приложение, которое требует использования полосы прокрутки на пользовательском представлении. Проблема, с которой я столкнулся, заключается в том, что моя пользовательская высота просмотра будет постоянно изменяться при добавлении пользователем новых элементов. Я подозреваю, что это не очень необычная проблема, но чтобы усложнить ситуацию, я фактически не добавляю новые объекты в свой пользовательский вид, я просто рисую растровые изображения на холсте. Причина, по которой мне хлопотно, - это когда Android раздувает макет, он устанавливает размер как то, что я ему скажу (0dip), и когда я добавляю Bitmaps, он просто меняет размер, чтобы заполнить Scrollview; таким образом, всякий раз, когда пользовательский вид рисует изображение за пределами текущих ограничений по высоте, вместо прокрутки приложение просто отключает изображение для поддержания текущей высоты.

(Это приложение для карточной игры, поэтому я хотел развернуть свою текущую колоду в удобном для просмотра и редактирования).

Вот соответствующий код:

public class DeckEdit extends Activity implements FilterQueryProvider  {

static final int PROGRESS_DIALOG = 0;
private Deck deck;
private CardListAdapter lstAdpt;
private ArrayList<CardImage> cards;
private ProgressDialog progressDialog;
private ProgressThread progressThread;
private String[] cardList;
private DeckEditCardView deckGrid;
private ScrollView sc;
protected Cursor cursor;

private EditText filterText = null;
ArrayAdapter<String> adapter = null;

public void onCreate(Bundle savedInstanceBundle){
    super.onCreate(savedInstanceBundle);
    deck = new Deck();
//This is what stores the Card Images that I draw to the canvas with
    cards = new ArrayList<CardImage>();

    setContentView(R.layout.deck_edit_layout);

    sc = (ScrollView) findViewById(R.id.deck_scroller);
    deckGrid = (DeckEditCardView) findViewById(R.id.deck_grid);

    filterText = (EditText) findViewById(R.id.card_search_box);
    filterText.addTextChangedListener(filterTextWatcher);


    pickDeck();
}

И тогда это вызывается после загрузки колоды

private void finishSetup(){
    //this is where I set up the deckGrid to have all the cards and then
    deckGrid.setCards(cards);
    //draw them to the screen
    deckGrid.invalidate();
    //This is where I realized that the height value might be causing the problem
    Log.d("finishSetup()", "deckGrid width: "+deckGrid.getWidth());
    Log.d("finishSetup()", "deckGrid height: "+deckGrid.getHeight());
}

Класс DeckEditCardView содержит этот

public class DeckEditCardView extends View implements OnTouchListener {
private ArrayList<CardImage> cards;

private int X_COLS;
@SuppressWarnings("unused")
private int Y_ROWS;
private final int COL_WIDTH;
private final int ROW_HEIGHT;
private Context context;

private final int X_PADDING = 2;
private final int Y_PADDING = 2;
private final int X_CARD_OVERLAY = 7;
private final int Y_CARD_OVERLAY = 5; 


public DeckEditCardView(Context context) {
    super(context);
    cards = new ArrayList<CardImage>();
    int cardWidth = getResources().getDrawable(R.drawable.back).getIntrinsicWidth();
    int cardHeight = getResources().getDrawable(R.drawable.back).getIntrinsicHeight();
    COL_WIDTH = (X_PADDING+(X_CARD_OVERLAY*3)+cardWidth);
    Log.d("DECV","COLWIDTH 1: "+COL_WIDTH);
    ROW_HEIGHT = (Y_PADDING+(Y_CARD_OVERLAY*3)+cardHeight);
    Log.d("DECV","ROWE_HEIGHT 1: "+ROW_HEIGHT);
}

public DeckEditCardView(Context context, AttributeSet attrs) {
    super(context, attrs);
    cards = new ArrayList<CardImage>();

    int cardWidth = getResources().getDrawable(R.drawable.back).getIntrinsicWidth();
    int cardHeight = getResources().getDrawable(R.drawable.back).getIntrinsicHeight();
    COL_WIDTH = (X_PADDING+(X_CARD_OVERLAY*3)+cardWidth);
    Log.d("DECV","COLWIDTH 2 : "+COL_WIDTH);
    ROW_HEIGHT = (Y_PADDING+(Y_CARD_OVERLAY*3)+cardHeight);
    Log.d("DECV","ROWE_HEIGHT 2: "+ROW_HEIGHT);
}

/*
public DeckEditCardView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    cards = new ArrayList<CardImage>();
    int width = getWidth();
    int height = getHeight();
    int cardWidth = getResources().getDrawable(R.drawable.back).getIntrinsicWidth();
    int cardHeight = getResources().getDrawable(R.drawable.back).getIntrinsicHeight();
    COL_WIDTH = (X_PADDING+(X_CARD_OVERLAY*3)+cardWidth);
    Log.d("DECV","COLWIDTH 3: "+COL_WIDTH);
    ROW_HEIGHT = (Y_PADDING+(Y_CARD_OVERLAY*3)+cardHeight);
    Log.d("DECV","ROWE_HEIGHT 3: "+ROW_HEIGHT);
    X_COLS = (width/COL_WIDTH);
    Y_ROWS = (height/ROW_HEIGHT);

}
*/    
@Override
public void onFinishInflate(){
    super.onFinishInflate();
    //this.
}

public void onSizeChanged(int w, int h, int oldw, int oldh){
    int width = getWidth();
    int height = getHeight();
    X_COLS = (width/COL_WIDTH);
    Y_ROWS = (height/ROW_HEIGHT);

}



public Point getNextCardPoint(Point curP, boolean sameCard){
    Point p=null;
    if (sameCard)
        p = new Point(curP.x+X_CARD_OVERLAY,curP.y+Y_CARD_OVERLAY);
    else { //need to be on the same column
        if (point2Col(curP)+1<X_COLS)
            p = new Point(COL_WIDTH*(point2Col(curP)+1)+X_PADDING,
                ROW_HEIGHT*(point2Row(curP))+Y_PADDING);
        else {//add to new column
            if (point2Row(curP)+1 > Y_ROWS)
                Y_ROWS++;

            p = new Point(X_PADDING,
                    ROW_HEIGHT*(point2Row(curP)+1)+Y_PADDING);
        }
    }
    return p;
}

public void setCards(ArrayList<CardImage> cards){
    this.cards = cards;
}

private int point2Col(Point p){
    return p.x / COL_WIDTH;
}
private int point2Row(Point p){
    return p.y / ROW_HEIGHT;
}


@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //ScrollView s = new ScrollView(context);
    //s.addView(canvas);
    int length = cards.size();
    CardImage c;
    for (int i = 0; i < length; i++) {
        //Log.d("onDraw", "output a card");
        c = cards.get(i);
        canvas.drawBitmap(c.getBitmap(), c.getX(), c.getY(), null);
    }
}

@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
    // TODO Auto-generated method stub
    return false;
}
}

Итак, в заключение я не знаю, как разрешить пользователю прокручивать и видеть карты, которые не подходят на экране (почти гарантировано, что полностью построенная колода возьмет полосу прокрутки, чтобы увидеть все из них. В лучшем случае с этим кодом он поместит все изображения карт, которые мне нужны, но те, которые идут на экран, я не знаю, что делать:/

И, наконец, мой файл Layout.xml      

<com.xeroxchange.ydd.DeckEditCardView android:layout_weight="2" 
     android:id="@+id/deck_grid" 
     android:layout_width="fill_parent" 
     android:layout_height="0dip"></com.xeroxchange.ydd.DeckEditCardView>
</ScrollView>       
<LinearLayout android:layout_weight="1" 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

        <!-- Pretty hint text, and maxLines -->
<EditText android:id="@+id/card_search_box" 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="type to filter"
    android:inputType="text"
    android:maxLines="1"/>

    <!-- Set height to 0, and let the weight param expand it -->
    <!-- Note the use of the default ID! This lets us use a 
         ListActivity still! -->
    <ListView android:id="@+id/card_list"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="2" 
    /> 

</LinearLayout>

</LinearLayout>
Теги:
android-custom-view

1 ответ

1
Лучший ответ

Ваш макет не работает должным образом, потому что DeckEditCardView не измеряет себя. Вы должны переопределить метод View.onMeasure() в классе DeckEditCardView и установить измеренный размер в зависимости от содержимого представления. В вашем XML файле макета вы должны указать wrap_content как высоту DeckEditCardView.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню