GridLayout get buttons to fit area - android

I am designing a game for android. The code already works, but I am having some issues with the UI side of things. All the Layout types are confusing and never seem to have their attributes helpfully defined. Essentially, I am looking to make my buttons, that are being added programmatically, fill out the entire space at the bottom of the screen cleanly. There could be between 2 and 6 buttons, depending on the difficulty setting the player chooses. But ultimately, I would even just settle for a layout that fits all 6 buttons evenly here. I am not exactly sure why this does not fill out the whole area indicated by the .xml designer. I have tried to provide the relevant parts below, but happy to add additional details on request.
This is the initial XML for the grid layout
<GridLayout
android:layout_width="match_parent"
android:layout_height="182dp"
android:rowCount="2"
android:columnCount="3"
android:id="#+id/buttonsLayout"
android:layout_gravity="center"></GridLayout>
And setting up the buttons here:
private static void setButtons() {
for (int i = 0; i < GlobalValues.numberOfColors; i++) {
Button b = new Button(mainActivity);
ImageView IV = new ImageView(mainActivity);
switch (i) {
case 0:
IV.setImageResource(R.drawable.red);
b.setId(i);
break;
case 1:
IV.setImageResource(R.drawable.green);
b.setId(i);
break;
case 2:
IV.setImageResource(R.drawable.blue);
b.setId(i);
break;
case 3:
IV.setImageResource(R.drawable.yellow);
b.setId(i);
break;
case 4:
IV.setImageResource(R.drawable.purple);
b.setId(i);
break;
case 5:
IV.setImageResource(R.drawable.cyan);
b.setId(i);
break;
default:
break;
}
b.setBackgroundDrawable(IV.getDrawable());
b.setOnClickListener(new Button.OnClickListener() {
public void onClick(View view) {
UI.UpdateColor(view);
}
});
buttonsLayout.addView(b);
}
}
And finally, here is what it currently looks like. It is clearly not making use of the whole area very well, and I am not sure why.

Align Buttons in GridLayout might help you. I know it's not exactly your case, but you stated that for now it's good enough to solve it for 6 buttons, so this might work. BTW if I were you I would have different layouts depending on the number of buttons to make them nice. But starting with 6 is the way.

Related

Icon not showing in FloatingActionButton after changed programmatically

I have an AppCompatActivity with a TabLayout and a FloatingActionButton that I change it's icons depending on which tab is currently displaying.
When I programmatically change the drawable of FloatingActionButton using setImageDrawable or setImageResource, the new icon does not show up, just the blank background of the button.
Strangely enough, if I hide and show the FloatingActionButton after I programmatically changed it's icon, it shows up.
This is the part where I change the icon:
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout) {
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
switch (position) {
case 0:
floatingActionButton.setImageDrawable(ContextCompat.getDrawable(mMainActivity, R.drawable.ic_save_24dp));
if (!floatingActionButton.isShown()) floatingActionButton.show();
mNavigationView.getMenu().getItem(1).setChecked(true);
break;
case 1:
floatingActionButton.setImageDrawable(ContextCompat.getDrawable(mMainActivity, R.drawable.ic_add_24dp));
if (!floatingActionButton.isShown()) floatingActionButton.show();
mNavigationView.getMenu().getItem(2).setChecked(true);
break;
case 2:
floatingActionButton.hide();
mNavigationView.getMenu().getItem(3).setChecked(true);
break;
}
}
});
Before:
After I programmatically changed it to a "plus" vector drawable:
Expected:
So, my question is: What is causing this, and how can it be solved?
I also had this problem and I solved by adding a call to the hide method
mFloatingActionButton.setImageDrawable(getDrawable(R.drawable.default_fab_icon));
mFloatingActionButton.hide();
mFloatingActionButton.show();
I had tried .invalidate() but that did not work. This seems to be a problem when switching fragments. I experienced it whilst using the Navigation AndroidX components.
I don't think this is the best solution but I tried a lot and only this worked - there's no flickering effect.
It is a known bug: https://issuetracker.google.com/issues/117476935
Just upgrade to com.google.android.material:material:1.1.0-beta02 which fixes this issue.

Textview with background color

I am new to android. I got stuck while doing an application.I have taken 5 textviews with time slots,I would like to show that when I click one text view it should change its background color and when I click another textview the first text view's background color has to disappear and present text view's color has to be highlight.
Here I am posting my code:
public void onClick(View v) {
switch (v.getId()){
case R.id.time_slot_one:
setTimeSlotOne.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
case R.id.time_slot_two:
setTimeSlotTwo.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
case R.id.time_slot_three:
setTimeSlotThree.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
case R.id.time_slot_four:
setTimeSlotFour.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
case R.id.time_slot_five:
setTimeSlotFive.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
}
A simple way would be to create a disable Background function that will be called each time you click a new one.
public void removeBackgroundColors() {
setTimeSlotOne.setBackgroundColor(Color.WHITE);
setTimeSlotTwo.setBackgroundColor(Color.WHITE);
setTimeSlotThree.setBackgroundColor(Color.WHITE);
setTimeSlotFour.setBackgroundColor(Color.WHITE);
setTimeSlotFive.setBackgroundColor(Color.WHITE);
}
now simply change your code to:
case R.id.time_slot_two:
removeBackgroundColors();
setTimeSlotTwo.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
...
Even simpler is to call it before your case statement, depending on what actions you want to take.
Use if else to setBackground color, for example ; if onclick of firsttextview set its color and on click of second change firsttextview color and set seconds color
You have to change the color of all Textviews.
Example t1 is selectable change t1's color as selected and other textviews as unselected,so on for rest of the textviews
It would be better if you use radio group which handles all clicks and selection and highlighting if you have many textviews.
Please check below url.
Url
In that link use answer by Sanjeet Ajnabee. It is excellent. I have been using it.

Android One Activity Transition Different Views

I was wondering if someone can advise what the best way to do the following: I'm creating an application where I'm asking the user a question and the user either answers the question or proceeds to the next question with fade in and fade out animation using animator instead of anim. As of now, I have one activity and in the activity I would load the layout that I have created in XML and then remove the view and load a new view.
I'm not sure if this is the best way to present multiple views in one Activity and prevent the need to use multiple activities. The reason why I'm doing this is because I have several objects that I'm storing data into based on the category of the question (whether is math, science, social studies, etc).
Here is a picture if it helps visualize:
If there is a better way to do this, please let me know. The only issue I'm having with this is that the activity A java class is growing in code because I have to handle everything there despite having the classes of the objects defined in other java files. Thank you.
I think you can build layout like this
RelativeLayout(see the structure) Set layout1 android:visibility="visible" and layout2 android:visibility="invisible" at first in .xml
layout1 = findViewById(R.id.layout1);
layout1.setVisibility(View.VISIBLE);
layout2 = findViewById(R.id.layout2);
layout2.setVisibility(View.GONE);
Button buttonNext = (Button)findViewById(R.id.buttonNext);
buttonNext.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View v) {
layout1.setVisibility(View.GONE);
layout2.setVisibility(View.VISIBLE);
viewTransAnimation();
}
});
And set your animation in viewTransAnimation(), example:
private void viewTransAnimation() {
layout2.setScaleX(0.1f);
layout2.setPivotX(layout2.getX() + layout2.getLeft() );
layout2.animate()
.scaleX(1)
.setDuration(500)
.setInterpolator(new AccelerateInterpolator())
.start();
}
Then it will change to layout2 after you click it. (use some flag make the animation only work once for your requirement.)
You can also replace 2 view with 2 RelativeLayout and do it in the same way.

Create a scrollable LinearLayout without a ScrollView

I spent a good part of a day looking into scrolling content in Android. However, in my app I need to apply a custom type of scrolling that contains among other things a listview. A listview has its own scrolling and a scrollview should never be used with a list view together.
But there must be some intrinsic scroll functionality for views. The documentation on View does indicate support but the methods provided do not seem to provide any listeners to detect scrolling.
A scrollview also is built on a FrameLayout which would also be problematic in my app.
You can make a LinearLayout scrollable with:
android:isScrollContainer="true"
but this doesn't seem to do anything.
In fact you can even set the scrollbars for a LinearLayout:
android:scrollbars="vertical"
but that also doesn't seem to do anything.
I don't want to control scrolling but rather have a listener that detects scrolling on the screen regardless whether a listview, framelayout or any other control is visible. I guess what I am looking for is writing my own custom ScrollView control but without the limitations of its FrameLayout and all the unnecessary overhead that I don't need. Any suggestions?
On way to resolve above problem is to have 2 ScrollView, one is the outer ScrollView that contain all the view and other inner Scrollview instead of listview and adding the items inside LinearLayout dynamically(Inside inner ScrollView)
Actually after doing some research, I come up with a solution for this problem:
At first I want to explain the problem in a very simple way.
1.LinearLayout will be scrollable.
2.To do this we can use ScrollView but sometimes we need to use ListView inside LinearLayout.
3.We know that inside ScrollView we cannot use another scrollview like ListView
How to solve that?
ListView is scrollable inherently so we can add header and footer in the ListView. As a conclusion:
1.Create Layout header.xml and footer.xml and list.xml
2.Find the ListView reference from list.xml in the main activity and dynamically add header and footer in the ListView reference.
Here is what seems like a viable solution which I tested out but not thoroughly. Create a custom control that extends a LinearLayout and then override the dispatchTouchEvent:
#Override
public boolean dispatchTouchEvent(MotionEvent event)
{
MotionEvent vtev = MotionEvent.obtain(event);
final int actionMasked = event.getActionMasked();
float x = event.getRawX();
float y = event.getRawY();
switch (actionMasked)
{
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int z = 0;
z++;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_POINTER_DOWN:
{
final int index = event.getActionIndex();
break;
}
case MotionEvent.ACTION_POINTER_UP:
break;
}
boolean ret = super.dispatchTouchEvent(event);
return ret;
}
}
You can then place child controls inside this custom LinearLayout and detect motion events, even when ListViews and ScrollViews are present. This doesn't mess with their own scrolling.

two different layouts for one activity

Is it possible to have two different layouts for different cases in the same activity or do I have to use intent to call another activity with a different layout
Yes its possible. You can use as many layouts as possible for a single activity but obviously not simultaneously. You can use something like:
if (Case_A)
setContentView(R.layout.layout1);
else if (Case_B)
setContentView(R.layout.layout2);
and so on...
Yes this is also possible with switch case
I already tried this code....
switch (condition) {
case 1:
setContentView(R.layout.layout1);
break;
case 2:
setContentView(R.layout.layout2);
break;
case 3:
setContentView(R.layout.layout3);
break;
default:
setContentView(R.layout.main);
break;
}
I suggest using Fragments
It will be helpful if you can explain more to find other solutions if your not ok with fragments
Edit
Use android support libraries for supporting lower OS versions
Edit2
if you want to use two xml you can combine two xml into one and use it
<include layout="#layout/YOURXMLNAME1" />
<include layout="#layout/YOURXMLNAME2" />
this is also useful while using layout again in many cases
There are a number of ways to go about this. The other answers include at least two approaches - using setContentView depending on the case and using fragments. There is one more I'd like to talk about. Say for instance, you include two layouts
<include
android:id = "#+id/layout1"
layout = .../>
<include
android:id = "#+id/layout2"
layout = ...
android:visibility = "gone"/>
In your java code, you can then hide or show your layouts depending on the use case. For instance, setting the content view to show the layout above shows layout1. When user clicks next button, you can then get a reference to layout1 and set it's visibility to gone and layout2's visibility to visible.
LinearLayout layout1 = findViewById(R.id.layout1);
LinearLayout layout2 = findViewById(R.id.layout2);
buttonNext.setOnClickListener(new View.OnClickListener()
{
layout1.setVisibility(View.GONE);
layout2.setVisibility(View.VISIBLE);
});
Here is best solution for you ViewFlipper.
ViewFlipper is a Simple ViewAnimator that will animate between two or more views that have been added to it. Only one child is shown at a time. If requested, can automatically flip between each child at a regular interval. Here is good example of viewflipper.
You can also look at this.
EDIT: -One StackoverFlow answer for you

Categories

Resources