Ответ 1
Наконец-то я нашел ответ на этот вопрос! Это немного хаки, но не слишком много. Единственными минусами являются:
- Он использует API 3.0+. Серьезно, хотя Google, какой смысл выпускать новые версии Android, если мы не сможем их использовать?/Декламация.
- Вы должны заменить
MenuItem
на свой собственныйView
.ImageView
довольно похож на стандартный, но он пропускает такие функции, как длительное нажатие, чтобы увидеть подсказку и, возможно, другие вещи. - Я не тестировал его много.
Хорошо, вот как мы это делаем. Измените Activity
onCreateOptionsMenu()
на следующее:
View mAddListingButton;
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.activity_main, menu);
// Find the menu item we are interested in.
MenuItem it = menu.findItem(R.id.item_new_listing);
// Create a new view to replace the standard one.
// It would be nice if we could just *get* the standard one
// but unfortunately it.getActionView() returns null.
// actionButtonStyle makes the 'pressed' state work.
ImageView button = new ImageView(this, null, android.R.attr.actionButtonStyle);
button.setImageResource(R.drawable.ic_action_add_listing);
// The onClick attributes in the menu resource no longer work (I assume since
// we passed null as the attribute list when creating this button.
button.setOnClickListener(this);
// Ok, now listen for when layouting is finished and the button is in position.
button.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom)
{
// Apparently this can be called before layout is finished, so ignore it.
// Remember also that it might never be called with sane values, for example
// if your action button is pushed into the "more" menu thing.
if (left == 0 && top == 0 && right == 0 && bottom == 0)
return;
// This is the only way to get the absolute position on the screen.
// The parameters passed to this function are relative to the containing View
// and v.getX/Y() return 0.
int[] location = new int[2];
v.getLocationOnScreen(location);
// Ok, now we know the centre location of the button in screen coordinates!
informButtonLocation(location[0] + (right-left)/2, location[1] + (bottom-top)/2);
}
});
it.setActionView(button);
mAddListingButton = it.getActionView();
return true;
}
И затем у вас есть функция, которая обновляет ваш полезный вид инструкций с расположением кнопки и перерисовывает ее:
private void informButtonLocation(int cx, int cy)
{
MyHelpView v = (MyHelpView)findViewById(R.id.instructions);
v.setText("Click this button.");
v.setTarget(cx, cy);
}
Наконец, сделайте свой необычный пользовательский вид, который рисует стрелку (рядом) с кнопкой. В вашем методе onDraw
вы можете преобразовать координаты экрана обратно в координаты Canvas
, используя ту же функцию getLocationOnScreen
. Что-то вроде этого:
@Override
public void onDraw(Canvas canvas)
{
int[] location = new int[2];
getLocationOnScreen(location);
canvas.drawColor(Color.WHITE);
mPaint.setColor(Color.BLACK);
mPaint.setTextSize(40);
mPaint.setAntiAlias(true);
mPaint.setTextAlign(Align.CENTER);
canvas.drawText(mText, getWidth()/2, getHeight()/2, mPaint);
// Crappy line that isn't positioned right at all and has no arrowhead.
if (mTargetX != -1 && mTargetY != -1)
canvas.drawLine(getWidth()/2, getHeight()/2,
mTargetX - location[0], mTargetY - location[1], mPaint);
}
(Но, очевидно, вам нужно скопировать целевое местоположение с размером холста). Если вы идете по тому же методу, что и Google, на котором вы просматриваете представление по всему экрану, вам не придется беспокоиться об этом, но это более навязчиво. Метод Google определенно не использует какие-либо частные API (удивительно). Проверьте Cling.java
в коде Launcher2.
Кстати, если вы посмотрите на источник аналогичной реализации Google для этой пусковой установки (они почему-то называют экран инструкций a Cling
), вы можете видеть, что он еще более взломан. Они в основном используют абсолютные позиции экрана, определяемые использованием макета.
Надеюсь, это поможет людям!