Android画廊冻结屏幕直到滚动

时间:2012-05-27 13:00:42

标签: android gallery freeze

我有一个全屏自定义图库。画廊的元素有按钮和其他互动区域。一些用户界面是通过在画廊前弹出的对话框完成的;当一个对话框被解除时,用户将被带回画廊。

大部分时间,这都很好。但是,有时,在关闭对话框后,按钮会停止用户输入。另一方面,画廊仍然滚动。更奇怪的是,只要我滚动图库,系统就会处理我认为失败的点击(弹出对话框等)。

很容易说主UI线程已被锁定。为什么锁定?我该如何解锁?任何帮助将不胜感激。以下是该课程的完整代码。

更新。图库中的一个元素是HorizontalScrollView。当我尝试滚动它时,鼠标消息通过;我走过它们,看到scrollBy()invalidate()被正确调用了。然后我打印出消息队列。通过主循环的唯一事件是1006,我假设是Touch事件。 Draw事件,1000,永远不会成功。一旦我来回滚动图库 - 瞧瞧 - 消息队列开始接收1000,所以HorizontalScrollView滚动得很好!

所以问题就变成了:什么停止Draw事件,以及如何确保它们被发送到队列?

public class PlayerGallery extends Gallery
{
  // 4 buttons to display
  private final static int BUT_BIRD = 0;
  private final static int BUT_SCORE = 1;
  private final static int BUT_ROUND = 2;
  private final static int BUT_MOVE = 3;
  private final static int N_BUTTONS = 4;

  // button images
  private final static Drawable[] imgButtons =
  {
    WonDraw.WW.bird,
    WonDraw.WW.scores,
    WonDraw.WW.moveSumm,
    WonDraw.WW.lastMove,
  };

  // individual player views
  private PlayerView[] views;

  // card that was clicked in the current player view
  private Card clickedCard = null;

  // wonder that was clicked in the current player view
  private Player clickedWonderPlayer = null;

  // one player
  private final class PlayerView extends RelativeLayout
    implements OnClickListener
  {
    // base view ID for the buttons
    private final static int BUT_VIEW_ID = 200;

    // player to display
    final Player player;

    // drawing data
    private PlayerDisplay pd = null;

    // the sub-view on top that shows player's hand
    private HandView handView = null;

    // button that takes user into bird's view
    private final GlassButton[] buttons = new GlassButton[N_BUTTONS];

    public PlayerView(Player player)
    {
      super(WonActivity.W.getApplicationContext());
      setBackgroundColor(Color.TRANSPARENT);
      this.player = player;

      RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
          LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
      lp.addRule(ALIGN_PARENT_TOP);
      handView = new HandView();
      addView(handView, lp);

      for (int i = 0; i < buttons.length; ++i)
      {
        lp = new RelativeLayout.LayoutParams(
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        if (i % 2 == 0)
          lp.addRule(ALIGN_PARENT_RIGHT);
        else
          lp.addRule(LEFT_OF, buttons[i - 1].getId());

        lp.addRule(BELOW, i / 2 == 0 ? handView.getId() : buttons[i - 2].getId());
        GlassButton but = new ImgGlassButton(GlassButton.ROUND, imgButtons[i]);
        but.setId(BUT_VIEW_ID + i);
        but.setOnClickListener(this);
        buttons[i] = but; addView(but, lp);
      }
    }

    // reset for the next player
    void reset(boolean useBigCards)
    {
      pd = WonActivity.W.getDisplay(player.id, useBigCards);

      if (useBigCards)
      {
        handView.pd = pd;
        handView.hand = WonActivity.W.getCurrentHand();
        handView.setVisibility(VISIBLE);
        handView.requestLayout();
        handView.scrollTo(0, 0);
      }
      else
      {
        handView.pd = null;
        handView.hand = null;
        handView.setVisibility(GONE);
      }

      for (int i = BUT_ROUND; i <= BUT_MOVE; ++i)
        buttons[i].setEnabled(Table.T.movesAvailable());

      invalidate();
    }

    @Override
    protected void dispatchSetPressed(boolean pressed)
    {
      // if I don't do that, bird button gets pressed when I scroll the gallery!
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
      if (event.getAction() == MotionEvent.ACTION_DOWN)
      {
        int x = (int)event.getX();
        int y = (int)event.getY();

        clickedCard = pd.findSmallCard(x, y);
        clickedWonderPlayer = clickedCard == null && pd.isInWonder(x, y) ?
          player : null;
      }
      return super.onTouchEvent(event);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
      super.onMeasure(MeasureSpec.makeMeasureSpec(WonActivity.W.getWidth() - 2, MeasureSpec.EXACTLY),
          MeasureSpec.makeMeasureSpec(WonActivity.W.getHeight(), MeasureSpec.EXACTLY));
      setBackgroundColor(Color.TRANSPARENT);
      setBackgroundDrawable(WonDraw.W.getWood());
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
      super.onDraw(canvas);
      if (pd == null) return;

      canvas.save();
      pd.draw(canvas, handView.hand, true);
      canvas.restore();
    }

    public void onClick(View v)
    {
      switch (v.getId() - BUT_VIEW_ID)
      {
        case BUT_BIRD:
          WonActivity.W.switchToBird(player.id);
          break;

        case BUT_SCORE:
          WonActivity.W.showScoreDlg();
          break;

        case BUT_ROUND:
          WonActivity.W.showRoundDlg();
          break;

        case BUT_MOVE:
          break;
      }
    }
  };

  // custom adapter for the gallery: provides circular functionality
  private class PGAdapter extends BaseAdapter
  {
    public int getCount()
    {
      return Integer.MAX_VALUE;
    }

    public Object getItem(int position)
    {
      return position;
    }

    public long getItemId(int position)
    {
      return position;
    }

    public View getView(int position, View convertView, ViewGroup parent)
    {
      return views[position % views.length];
    }
  };

  public PlayerGallery()
  {
    super(WonActivity.W.getApplicationContext());
    setSpacing(0);
    setBackgroundColor(Color.TRANSPARENT);

    views = new PlayerView[Table.T.getPlayerCount()];

    for (int i = 0; i < Table.T.getPlayerCount(); ++i)
      views[i] = new PlayerView(Table.T.getPlayer(i));

    setAdapter(new PGAdapter());
    setHorizontalFadingEdgeEnabled(false);
    setVerticalFadingEdgeEnabled(false);
  }

  // reset for the next player
  void changeMovingPlayer()
  {
    for (int i = 0; i < views.length; ++i)
      views[i].reset(i == WonActivity.W.getCurrentPlayerID());
    setViewedPlayer(Math.max(WonActivity.W.getCurrentPlayerID(), 0));
  }

  // set the player whose buildings to view
  void setViewedPlayer(int index)
  {
    int pos = Integer.MAX_VALUE / 2;
    pos -= pos % views.length;
    setSelection(pos + index);
    views[index].requestFocus();
    views[index].invalidate();
  }

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
  {
    int kEvent = e2.getX() > e1.getX() ?
      KeyEvent.KEYCODE_DPAD_LEFT :
      KeyEvent.KEYCODE_DPAD_RIGHT;
    onKeyDown(kEvent, null);

    return true;
  }

  @Override
  public boolean onTouchEvent(MotionEvent event)
  {
    boolean b = super.onTouchEvent(event);

    switch (event.getAction())
    {
      case MotionEvent.ACTION_DOWN:
        return true;

      case MotionEvent.ACTION_UP:
        if (event.getEventTime() - event.getDownTime() < WonActivity.CLICK_MS)
        {
          if (clickedCard != null)
            WonActivity.W.showCardDlg(clickedCard);
          else if (clickedWonderPlayer != null)
            WonActivity.W.showWonderDlg(clickedWonderPlayer);
        }

        clickedCard = null;
        clickedWonderPlayer = null;
        break;
    }

    return b;
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
  {
    int w = MeasureSpec.getSize(widthMeasureSpec);
    int h = MeasureSpec.getSize(heightMeasureSpec);

    WonActivity.W.resize(w, h);
    super.onMeasure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY),
        MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY));
  }
}

0 个答案:

没有答案