Existe-t-il un moyen de rendre une vue au-dessus de la barre d'actions? Je veux créer une petite boîte à astuces qui dirigera l'utilisateur vers un élément de la barre d'action. Je sais qu'un Toast
avec une vue d'ensemble sera rendu au-dessus de la barre d'action. Est-ce que quelqu'un sait comment faire cela avec une vue?
J'ai tenté d'utiliser FrameLayout
avec layout_gravity="top"
et gonfler une vue, puis l'ajouter à la présentation de l'activité en cours.
Je vous remercie d'avance.
Edit : Voici une image de ce que je pensais:
Edit : Peut-être que des détails supplémentaires sont nécessaires. Je cherche un moyen, ou pour savoir s'il est même possible d'ajouter une vue à la hiérarchie des vues de l'activité pour qu'elle soit restituée en dernier.
Semblable à CSS, je veux un ordre d'index z plus élevé pour cette vue particulière (la boîte flottante bleue dans l'image), de sorte qu'elle soit rendue au-dessus de la région de la barre d'action dans l'activité. La vue n'est en aucun cas associée à la barre d'actions, elle est simplement dessinée par dessus.
Après avoir lutté avec moi-même un certain temps, voici la solution (testée - fonctionnant bien):
Les étapes générales sont les suivantes:
Voyons un peu de code.
Tout d'abord, créez une méthode pour aider à créer une vue wrapper. le wrapper sera placé entre tout l'écran et le contenu de votre application. étant un ViewGroup vous pourrez plus tard contrôler complètement son contenu.
private ViewGroup setContentViewWithWrapper(int resContent) {
ViewGroup decorView = (ViewGroup) this.getWindow().getDecorView();
ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0);
// Removing decorChild, we'll add it back soon
decorView.removeAllViews();
ViewGroup wrapperView = new FrameLayout(this);
// You should set some ID, if you'll want to reference this wrapper in that manner later
//
// The ID, such as "R.id.ACTIVITY_LAYOUT_WRAPPER" can be set at a resource file, such as:
// <resources xmlns:Android="http://schemas.Android.com/apk/res/Android">
// <item type="id" name="ACTIVITY_LAYOUT_WRAPPER"/>
// </resources>
//
wrapperView.setId(R.id.ACTIVITY_LAYOUT_WRAPPER);
// Now we are rebuilding the DecorView, but this time we
// have our wrapper view to stand between the real content and the decor
decorView.addView(wrapperView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
wrapperView.addView(decorChild, decorChild.getLayoutParams());
LayoutInflater.from(this).inflate(getActivityLayout(),
(ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(1), true);
return wrapperView;
}
Maintenant, interférer avec la création régulière de Activity , et au lieu d'utiliser setContentView , utilisez la méthode que nous avons créée.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// DON'T CALL `setContentView`,
// we are replacing that line with this code:
ViewGroup wrapperView = setContentViewWithWrapper(R.layout.activity_layout);
// Now, because the wrapper view contains the entire screen (including the notification bar
// which is above the ActionBar) I think you'll find it useful to know the exact Y where the
// action bar is located.
// You can use something like that:
ViewGroup actionBar = (ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(0);
int topOffset = actionBar.getTop();
// Now, if you'll want to add a view:
// 1. Create new view
// 2. Set padding top - use "topOffset"
// 3. Add the view to "wrapperView"
// 4. The view should be set at front. if not - try calling to "bringToFront()"
}
C'est à peu près ça.
Remarques
0
et 1
index)EDIT: Reportez-vous à la réponse @ CristopherOyarzúnAltamirano pour plus d'assistance sur les nouvelles versions Android versions
Bonne chance!
J'essayais de réaliser autre chose mais j'avais besoin d'une solution similaire à celle-ci. J'avais besoin de dessiner un calque opaque couvrant tout l'écran, même la barre d'action - un peu comme une boîte de dialogue. Je l'ai fait de cette façon:
ViewGroup vg = (ViewGroup)(getWindow().getDecorView().getRootView());
vg.addView(myNewView, params);
cela peut être utilisé pour dessiner n'importe quoi n'importe où sur l'écran.
Il existe un moyen beaucoup plus simple d'y parvenir. ActionBar conserve sa disposition dans la classe ActionBarContainer qui hérite simplement de FrameLayout. Donc, pour afficher quelque chose sur l'ActionBar, vous devez saisir une référence à ActionBarContainer et y ajouter votre propre vue personnalisée. Voici le code
int abContainerViewID = getResources().getIdentifier("action_bar_container", "id", "Android");
FrameLayout actionBarContainer = (FrameLayout)findViewById(abContainerViewID);
LayoutInflater myinflater = getLayoutInflater();
View customView = myinflater.inflate(R.layout.yourCustomeViewLayout, null);
actionBarContainer.addView(customView);
J'ai trouvé cette solution de contournement basée sur la réponse @Sean:
//This is for Jelly, ICS, Honeycomb
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2){
LayoutInflater.from(this).inflate(resContent, (ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(1), true);}
//This is for KitKat and Jelly 4.3
else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
LayoutInflater.from(this).inflate(resContent, (ViewGroup) (((ViewGroup) wrapperView.getChildAt(0)).getChildAt(0)), true);}
//This is for Ginger
else{
LayoutInflater.from(this).inflate(resContent, (ViewGroup) ((LinearLayout)((FrameLayout) wrapperView.getChildAt(0)).getChildAt(0)).getChildAt(1), true);}
J'ai trouvé un moyen beaucoup plus simple de le faire. Je viens d'appliquer Android: translationZ = "10dp" à la vue dont j'ai besoin pour couvrir la barre d'action.
J'ai choisi 10dp mais cela peut être tout ce que vous voulez tant qu'il est supérieur à l'élévation de la barre d'action
<ImageView
Android:layout_width="100dp"
Android:layout_height="100dp"
Android:translationZ="10dp"
Android:src="@drawable/potatoe" />
Ne vous inquiétez pas non plus de l'avertissement suivant de Android studio:
"translationZ ne peut pas être utilisé avec l'API <21".
Il sera ignoré, mais vous ne vous en souciez pas vraiment car la barre d'outils ne doit pas couvrir votre vue avec des API inférieures à 21.
Essayez d'utiliser ActionBar.setCustomView (). C'est le seul moyen de modifier l'apparence de cette zone de l'écran. Vous ne pouvez pas coller une vue dans la zone "au-dessus" de l'ActionBar, car cette zone est essentiellement contrôlée par le système. D'autre part, vous pouvez fournir votre propre mise en page pour cela.
Si vous expliquez plus en détail ce que vous essayez de faire, les répondants pourraient avoir de meilleures idées de conception.
https://github.com/michaelye/EasyDialogDemo
voir la démo ci-dessus, cela peut vous aider
dialog.setLocation(new location[])//point in screen
vous pouvez définir l'emplacement [] vous-même.
(Référence: http://www.vogella.com/articles/AndroidActionBar/article.html )
Vues personnalisées dans ActionBar
Vous pouvez également ajouter une vue personnalisée à ActionBar
. Pour cela, vous utilisez la méthode setCustomView
pour la classe ActionView
. Vous devez également activer l'affichage des vues personnalisées via la méthode setDisplayOptions()
en passant le ActionBar.DISPLAY_SHOW_CUSTOM
drapeau.
Par exemple, vous pouvez définir un fichier de mise en page qui contient un élément EditText
.
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/searchfield"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:inputType="textFilter" >
Cette disposition peut être affectée à ActionBar
via le code suivant. L'exemple de code allow attache un écouteur à la vue personnalisée.
package com.vogella.Android.actionbar.customviews;
import Android.app.ActionBar;
import Android.app.Activity;
import Android.os.Bundle;
import Android.view.KeyEvent;
import Android.widget.EditText;
import Android.widget.TextView;
import Android.widget.TextView.OnEditorActionListener;
import Android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getActionBar();
// add the custom view to the action bar
actionBar.setCustomView(R.layout.actionbar_view);
EditText search = (EditText) actionBar.getCustomView().findViewById(R.id.searchfield);
search.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
Toast.makeText(MainActivity.this, "Search triggered",
Toast.LENGTH_LONG).show();
return false;
}
});
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM
| ActionBar.DISPLAY_SHOW_HOME);
}
}
Utilisez le Android:actionLayout
dans votre fichier menu.xml.
<?xml version="1.0" encoding="utf-8"?><menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:id="@+id/menu_id"
Android:title="@string/menu_string_to_show"
Android:icon="@drawable/ic_menu_icon_name"
Android:showAsAction="always"
Android:actionLayout="@layout/action_button_foo" /></menu>
Créez ensuite votre mise en page action_button_foo.xml:
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:text="@string/menu_string_to_show"
Android:drawableLeft="@drawable/ic_menu_icon_name"
Android:background="@drawable/bg_btn_action_bar"
Android:clickable="true" />
Pour gérer le clic, procédez comme suit:
@Overridepublic boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my_menu, menu);
final MenuItem item = menu.findItem(R.id.menu_id);
item.getActionView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onOptionsItemSelected(item);
}
});
return super.onCreateOptionsMenu(menu);}
C'est si :)