I am using the library com.baoyz.swipemenulistview every thing is working good i want borders around each menu items, so that even if all menu item background is white a grey border is around the each item separating each other.
After looking into the code i have found that this can be implemented in following function of SwipeMenuView.java
private void addItem(SwipeMenuItem item, int id) {
LayoutParams params = new LayoutParams(item.getWidth(),
LayoutParams.MATCH_PARENT);
LinearLayout parent = new LinearLayout(getContext());
parent.setId(id);
parent.setGravity(Gravity.CENTER);
parent.setOrientation(LinearLayout.VERTICAL);
parent.setShowDividers(LinearLayout.SHOW_DIVIDER_BEGINNING);
parent.setLayoutParams(params);
parent.setBackgroundDrawable(item.getBackground());
parent.setOnClickListener(this);
addView(parent);
if (item.getIcon() != null) {
parent.addView(createIcon(item));
}
if (!TextUtils.isEmpty(item.getTitle())) {
parent.addView(createTitle(item));
}
}
As i am newbie for android world, i am unable to find the way to to draw border around menu item. Which function/method to look for in LinearLayout that have the capability to draw borders. Or how to draw border as shown
Ide : Android Studio 2.2.3
Link to library :
SwipeMenuListView Github
UPDATE
I have added GradeintDrawable to the function now border is there but here i cannot pass item.getBackground which will return (Drawable). How to set GradientDrawable.setColor (int color); with item.getBackground which will return Drawable;
private void addItem(SwipeMenuItem item, int id) {
LayoutParams params = new LayoutParams(item.getWidth(),
LayoutParams.MATCH_PARENT);
GradientDrawable drawable = new GradientDrawable();
drawable.setShape(GradientDrawable.RECTANGLE);
drawable.setStroke(1, Color.BLACK);
drawable.setCornerRadius(1);
//drawable.setColor(Color.GRAY); here i have to pass item.getBackground();
//like :
drawable.setColor(item.getBackground); //error because getBackground is of type drawable;
LinearLayout parent = new LinearLayout(getContext());
parent.setId(id);
parent.setGravity(Gravity.CENTER);
parent.setOrientation(LinearLayout.HORIZONTAL);
parent.setLayoutParams(params);
//parent.setBackgroundDrawable(item.getBackground());
parent.setBackgroundDrawable(drawable);
parent.setOnClickListener(this);
addView(parent);
if (item.getIcon() != null) {
parent.addView(createIcon(item));
}
if (!TextUtils.isEmpty(item.getTitle())) {
parent.addView(createTitle(item));
}
}
Related
I've been browsing the entire internet, but I could not find any answer to this question. I want to create a background, some image buttons, along with a bunch of moving graphics (circles). Since I do not know how to overwrite a xml layout with moving graphics, I chose to customly create my view, draw the background, the imageButtons and the circles (2D graphics).
public class GameView extends View implements UtilConstants
since I extended the View class, I had to call the super class constructor in my constructor
GameView(Context context) {
super(context);
this.context = context;
this.paint = new Paint();
}
and to implement the onDraw method, which acts like the java paintComponent
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // necessary for some reason
setGridBackground(); // sets the background
paint.setColor(Color.parseColor("#FF0000"));
canvas.drawCircle(this.x += 10, 300, 20, paint); //moves my graphics (ball) within the screen
drawScoreInLeftUpperCorner(canvas, 20); // paints a string text on the screen
setAbilitiesImages(); // places some imageButtons
try {
Thread.sleep(THREAD_REFRESH_RATE_MS);
} catch (InterruptedException ex) {
System.out.println(ex);
}
invalidate();
}
Now, to get to my problem:
I do not know how to set those ImageButtons !!! I am trying
private void setAbilititesImages() {
ImageButton imageButton = new ImageButton(this.context); // is this ok to put the argument this.context??
imageButton.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
imageButton.setImageResource(R.drawable.monster); // set my resource
RelativeLayout relativeLayout = findViewById(R.id.in_game_layout); // what is the purpose of this???
if (relativeLayout != null) { // it never enters this if, relativeLayout is always null
relativeLayout.addView(imageButton);
}
}
Aaaaand the image button never shows up...why is it necessary to use Relative/Linear layouts? That R.id.in_game_layout I created is just an empty RelativeLayout xml. Can't I just use something like
imageButton.setImageResource(R.drawable.monster); // set my resource
imageButton.setBounds(.....);
(View)this.add(imageButton); ???
ImageButton requires a parent view to be hosted in it. The parent View can be a RelativeLayout, a linearlayout or a ConstraintLayout.
In your case, the instance relativeLayout is always null because you not specify the view parent in which you do findViewById.
You should make something like :
RelativeLayout relativeLayout = view.findViewById(R.id.in_game_layout);
You need to add layout param to your parent Relative layout also to display your Image button appropriately.
Example
RelativeLayout relativeLayout = findViewById(R.id.relativeLayout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ImageButton imageButton = new ImageButton(this);
imageButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher_background,null));
relativeLayout.addView(imageButton,params);
I am having a problem with my AR object's pop up view. I can place one AR object and then its view shows the correct image. But then, if i were to place a new AR object, the previous images will get overwritten by the new one. So, for example, if i place a laptop object, its image will be a laptop. But then if i place a new object like the notebook, the laptop's image will get overwritten with that new one.
Here is a visual representation of what i am talking about:
I have tried different methods but still same result.
This is how they're declared:
private String objectName;
private int resID;
Here is where I place the object:
arFragment.setOnTapArPlaneListener(
(HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
if (plane.getType() != Plane.Type.HORIZONTAL_UPWARD_FACING){
return;
}
Anchor anchor = hitResult.createAnchor();
arranchors.addElement(anchor);
placeObject(arFragment, arranchors.lastElement(), selectedObject);
if(arranchors.size() >1)
{
spreadapart();
}
}
);
Here is how the different objects, object names, their images is picked:
(btw, object names also has this problem)
private void InitializeAssetsMenu(){
LinearLayout gallery = findViewById(R.id.asset_layout);
ImageView pencil = new ImageView(this);
pencil.setImageResource(R.drawable.pencil_thumb);
pencil.setContentDescription("pencil");
pencil.setOnClickListener(view -> {selectedObject = Uri.parse("Pencil_01.sfb");objectName= "Pencil"; resID= R.drawable.pencil_thumb;});
gallery.addView(pencil);
ImageView eraser = new ImageView(this);
eraser.setImageResource(R.drawable.eraser_thumb);
eraser.setContentDescription("eraser");
eraser.setOnClickListener(view -> {selectedObject = Uri.parse("Eraser_01(1).sfb");objectName="Eraser"; resID= R.drawable.eraser_thumb;});
gallery.addView(eraser);
ImageView laptop = new ImageView(this);
laptop.setImageResource(R.drawable.laptop_thumb);
laptop.setContentDescription("laptop");
laptop.setOnClickListener(view -> {selectedObject = Uri.parse("Laptop_01.sfb");objectName="Laptop"; resID= R.drawable.laptop_thumb;});
gallery.addView(laptop);
ImageView notebook = new ImageView(this);
notebook.setImageResource(R.drawable.notebook_thumb);
notebook.setContentDescription("notebook");
notebook.setOnClickListener(view -> {selectedObject = Uri.parse("Notebook.sfb");objectName="Notebook"; resID= R.drawable.notebook_thumb;});
gallery.addView(notebook);
}
And here is where i make the image view:
private Node createInfoCard(TransformableNode parent){
Node infoCard = new Node();
infoCard.setParent(parent);
infoCard.setEnabled(false);
infoCard.setRenderable(cardRenderable);
//TextView textView = (TextView)cardRenderable.getView();
//textView.setText(this.objectName);
ImageView imageView1 = (ImageView)cardRenderable.getView();
imageView1.setImageResource(resID); //here we will have a variable that will have different image for each respective object.
infoCard.setLocalPosition(new Vector3(0.0f, 0.25f, 0.0f));
parent.setOnTapListener(
(hitTestResult, motionEvent) -> {
infoCard.setEnabled(!infoCard.isEnabled());
spreadapart();
});
return infoCard;
}
I'm sure the issue has to do with the variable resID but I just don't understand how it's causing the overwriting.
I am using the Slider of Material component:
https://github.com/material-components/material-components-android/blob/master/docs/components/Slider.md
I am trying to display a label when the thumb is moving, which seem to be supported with the labelFormatter attribute.
here is what my code looks like:
Slider s = new Slider(context);
s.setLabelFormatter(new Slider.LabelFormatter() {
#NonNull
#Override
public String getFormattedValue(float value) {
return "MY STRING";
}
});
When I go line by line with debugger it goes through this function:
private void drawLabelText(#NonNull Canvas canvas, int width, int top) {
labelTextPaint.getTextBounds(labelText, 0, labelText.length(), labelTextBounds);
int left = trackSidePadding + (int) (thumbPosition * width) - labelTextBounds.width() / 2;
canvas.drawText(labelText, left, top - labelTextTopOffset - thumbRadius, labelTextPaint); }
but no text is displayed only the slider...
I am kind of new in androïd and I am surely missing something.
Thanks for help :)
EDIT 1:
Here is the whole code simplified :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CoordinatorLayout layout = new CoordinatorLayout(this);
setContentView(layout);
// I am Using Coordinator Layout for current activity so...
CoordinatorLayout.LayoutParams layoutParams = new CoordinatorLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
//Setting gravity to CENTER
layoutParams.gravity = Gravity.CENTER;
Slider slider = new Slider(this);
slider.setLabelFormatter(new Slider.LabelFormatter() {
#NonNull
#Override
public String getFormattedValue(float value) {
return "MY STRING";
}
});
layout.addView(slider, layoutParams);
}
But still not working ...
output result
https://youtu.be/obV4K-Nxu-0
EDIT 2:
Updating Material component from version: '1.2.0-alpha02' to version: '1.2.0-alpha05' fixed the issue.
Actually i wanted to comment but because of Reputation Constraints i couldn't,
Looks like you are adding a view programatically in your activity. Here i have implemented new MaterialComponent Slider with LabelFormatter
ViewGroup group = findViewById("YOUR_ACTIVITY_LAYOUT");
// I am Using Coordinator Layout for current activity so...
CoordinatorLayout.LayoutParams layoutParams = new CoordinatorLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
//Setting gravity to CENTER
layoutParams.gravity = Gravity.CENTER;
Slider slider = new Slider(this);
slider.setLabelFormatter(new Slider.LabelFormatter() {
#NonNull
#Override
public String getFormattedValue(float value) {
return "MY STRING";
}
});
group.addView(slider, layoutParams);
}
And then there you go...
I have a RecyclerView that contains a list of cards, each of which expand into child cards.
Each card has different text. I want that when the user clicks on a child card, it will expand to show the text inside. The expansion height is based on how much text the card contains.
I tried to measure the target height by using:
view.Measure(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent);
And then expanding the card to the Measured Height (see here).
However, it gives the same Measured Height to all of the cards.
Here is my code, which is based on this (more specifically the Xamarin version):
This is the main Adapter, which creates and binds the parent and the child cards:
public class HalachaExpandableAdapter : ExpandableRecyclerAdapter<HalachaParentViewHolder, HalachaChildViewHolder>, View.IOnClickListener
{
LayoutInflater _inflater;
bool expand;
int targetHeight;
bool wave = false;
public HalachaExpandableAdapter(Context context, List<IParentObject> itemList) : base(context, itemList)
{
_inflater = LayoutInflater.From(context);
}
public override void OnBindChildViewHolder(HalachaChildViewHolder childViewHolder, int position, object childObject)
{
var halachaChild = (HalachaChild)childObject;
childViewHolder.halachaChildTitle.Text = halachaChild.Title.ToString();
targetHeight = childViewHolder.halachaChildCard.Height;
childViewHolder.halachaChildCard.LayoutParameters.Height = 100;
childViewHolder.halachaChildCard.SetOnClickListener(this);
expand = childViewHolder.expand;
}
public override void OnBindParentViewHolder(HalachaParentViewHolder parentViewHolder, int position, object parentObject)
{
var halacha = (HalachaItem)parentObject;
parentViewHolder._halachaTitleTextView.Text = halacha.Title();
parentViewHolder._halachaContentTextView.Text = halacha.Content;
if (halacha.ChildObjectList.Count == 1)
wave = true;
}
public void OnClick(View v)
{
if (v.Height == 100)
{
AnimationCollapse anim = new AnimationCollapse(v, targetHeight, 100);
anim.Duration = 300;
v.StartAnimation(anim);
expand = false;
}
else
{
AnimationCollapse anim = new AnimationCollapse(v, 100, v.Height);
anim.Duration = 300;
v.StartAnimation(anim);
expand = true;
}
}
public override HalachaChildViewHolder OnCreateChildViewHolder(ViewGroup childViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.halachotListItem, childViewGroup, false);
return new HalachaChildViewHolder(view);
}
public override HalachaParentViewHolder OnCreateParentViewHolder(ViewGroup parentViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.halachotListHeader, parentViewGroup, false);
wave = false;
return new HalachaParentViewHolder(view);
}
}
I think this is where the code is needed to be done, but if you need some of the other code of the other classes, I will gladly post them. You can also look at the links above for reference to how this works.
Hope someone can help me.
Thanks!
I finally managed to solve the problem.
I needed to change the way I measured the view's wrap_content height to this:
v.Measure(MeasureSpec.MakeMeasureSpec(v.Width, MeasureSpecMode.Exactly), MeasureSpec.MakeMeasureSpec(ViewGroup.LayoutParams.WrapContent, MeasureSpecMode.AtMost));
The rest is the same.
Thanks to this post.
I dont know why do you want to find the height of the card , instead you can just wrap the child cards height to that of text and make child card invisible , as soon as user click a card , child card s visiblity will be turned to visible and card wih its text with the same height will appear !
The following image should represent an PhoneGap/Cordova app which is marked in blue.
The red area should be an Android Fragment.
Is it possible tho have an Android Fragment which overlays a PhoneGap Activity?
Edit: The overlaying Android Fragment should the tasks like image manipulation.
How do I have to write a PhoneGap plugin that communicates with the Fragment?
the way i did this was by writing a plugin that shows a custom dialog without border, background shadow, etc.
my execute() method looks like this:
#Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (resources == null)
resources = cordova.getActivity().getApplication().getResources();
if (package_name == null)
package_name = cordova.getActivity().getApplication().getPackageName();
if (inflator == null) {
inflator = cordova.getActivity().getLayoutInflater();
}
if (action.equals("show")) {
this.show(args, callbackContext);
return true;
}
return false; // Returning false results in a "MethodNotFound" error.
}
and the show() method contains something like this:
[...]
Runnable runnable = new Runnable() {
public void run() {
pinpad = new Dialog(cordova.getActivity());
pinpad.requestWindowFeature(Window.FEATURE_NO_TITLE);
Window window = pinpad.getWindow();
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
WindowManager.LayoutParams wlp = window.getAttributes();
wlp.gravity = Gravity.BOTTOM;
window.setAttributes(wlp);
pinpad.setCancelable(false);
pinpad.setContentView(view);
pinpad.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, (int) height);
pinpad.show();
}
};
this.cordova.getActivity().runOnUiThread(runnable);
[...]
if your window (the red part) has to be placed in some particular position (not in the center or at the bottom of the screen) then you have to pass coordinates from javascript to native plugin.