changing the background of a view inside my relativelayout - android

I'm having trouble with this layout that is a item in my grid adapter.
I'm using caldroid
I inflate my cell layout in the getview:
R.layout.calendar_view_date_cell.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rlCalendarViewCell"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white1"
>
<TextView
android:id="#+id/tvCalendarDayNr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:padding="5dp"
android:text="10"
android:textSize="20sp" />
<View
android:id="#+id/vCellBorder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/selected_border" >
</View>
</RelativeLayout>
I want to use the view that is inside the relativelayout for a border background.
I'm using this method to try and change the background of the cell (to show that this cell of the calendar is the one that has been pressed).
#Override
public void onSelectDate(Date date, View view) {
View vCellBorder = (View) view.findViewById(R.id.vCellBorder);
vCellBorder.setBackgroundResource(R.drawable.selected_border);
Toast.makeText(getApplicationContext(), ""+(date),
Toast.LENGTH_SHORT).show();
}
The weird thing is, in my date_cell preview I can already see the selected border. But when I run my app, I only see the background of the Relativelayout (color/white1).
If I change my method to:
#Override
public void onSelectDate(Date date, View view) {
view.setBackgroundResource(R.drawable.selected_border);
Toast.makeText(getApplicationContext(), ""+(date),
Toast.LENGTH_SHORT).show();
}
This up here works. But I dont want it like this, because I want the ability to change different backgrounds for the different layers of the layout.

I suspect that this is because the base class view doesn't know how to layout properly.
I would change the View to an ImageView and place it before the textview in the layout like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rlCalendarViewCell"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white1"
>
<ImageView
android:id="#+id/vCellBorder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/selected_border" />
<TextView
android:id="#+id/tvCalendarDayNr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:padding="5dp"
android:text="10"
android:textSize="20sp" />
</RelativeLayout>
Also in the code i would hide/unhide the view rather than changing its drawable
so
#Override
public void onSelectDate(Date date, View view) {
View vCellBorder = (View) view.findViewById(R.id.vCellBorder);
vCellBorder.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), ""+(date),
Toast.LENGTH_SHORT).show();
}
and obviously the view would start as GONE or INVISIBLE

My view was getting 0dp width and height. So thats why the background was not showing.
In the end I changed my view into a linearlayout and put my textview inside of it. and match_parent is working now. The 0dp was giving me the hint.

Related

Animating view to visible causes undesired animations on other views

I'm having some weird affects when trying to animate view from gone to visible. See attached gif.
I have a simple Switch, that toggles visibility of TextView. When TextView changes to visible, there is an undesired animation-like affect on the Button.
I've figured this is something to do with R.id.group layout height. See layout below.
When I remove ScrollView, and change R.id.group layout height to match_parent, it works correctly. But that is not the solution, since I ultimately need a ScrollView.
How to avoid button animation effect?
Source code:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Switch sw = view.findViewById(R.id.toggle);
TextView tv = view.findViewById(R.id.text);
sw.setOnCheckedChangeListener((button, isChecked) -> {
int visibility = isChecked ? View.VISIBLE : View.GONE;
tv.setVisibility(visibility);
});
}
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:padding="10dp"
>
<LinearLayout
android:id="#+id/group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
>
<Switch
android:id="#+id/toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="toggle"
/>
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Blabla\nblabla\nblabla\nblabla"
/>
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Self destruct"
/>
</LinearLayout>
</ScrollView>
Managed to find out workaround on the world wide web after all. Props to Sam Chen's anwser.
Basically, I needed to set LayoutTransition (aka animateLayoutChanges="true") for R.id.group layout, where Button resides, and enable CHANGING transition:
LayoutTransition transition = new LayoutTransition();
transition.enableTransitionType(LayoutTransition.CHANGING);
groupLayout.setLayoutTransition(transition);

Add foreground color and central icon to clickable view

I'm trying to achieve something like this!
Alternative to check box
How do I achieve this?
I tried creating a drawable with a central icon and a transparent background but the icon scales to fill the view when the drawable is set to the view foreground.
Also there is no support for setForground method for api level less than 23
I intend to achieve this dynamically when a view is clicked. Please help!!!
to achieve this view use relative layout like below code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:layout_width="90dp"
android:layout_height="120dp">
<ImageView
android:id="#+id/image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/demo_img_4" />
<LinearLayout
android:id="#+id/transp_ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#30000000"
android:gravity="center">
<ImageView
android:id="#+id/delete_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_delete_black_24dp" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//initialize views
setContentView(R.layout.activity_main);
image_view = findViewById(R.id.image_view);
delete_btn = findViewById(R.id.delete_btn);
transp_ll = findViewById(R.id.transp_ll);
//set transparent layout visibility gone
transp_ll.setVisibility(View.GONE);
//set click listener
image_view.setOnClickListener(this);
delete_btn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.delete_btn:
//write here delete button click functionality..
transp_ll.setVisibility(View.GONE);
break;
case R.id.image_view:
transp_ll.setVisibility(View.VISIBLE);
break;
}
}
You should add a transparent view that matches the parent dimensions over you view and add a image view in center of it.
You can adjust your transparency level to get the desired effect

Android List Below Toggle Buttons

I have a list that is intended to be below toggle buttons. The list grabs data from a server and then parses them. My XML is as follows:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ToggleButton
android:id="#+id/toggle_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textOff="Apps"
android:textOn="Apps" />
<ToggleButton
android:id="#+id/toggle_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/toggle_button1"
android:layout_weight="1"
android:textOff="VMs"
android:textOn="VMs" />
<ToggleButton
android:id="#+id/toggle_button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/toggle_button2"
android:layout_weight="1"
android:textOff="Groups"
android:textOn="Groups" />
<ListView
android:id="#+id/mylist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toggle_button1" />
</RelativeLayout>
Code for the actual fragment:
public class ProblemFragment extends SherlockListFragment
{
private SeparatedListAdapter list;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.getSherlockActivity().setContentView(R.layout.problem_layout);
list = new SeparatedListAdapter(this.getSherlockActivity(), new Layout(R.layout.separated_list_adapter_two_text, R.id.two_text_title, R.id.two_text_desc));
ToggleButton b1 = (ToggleButton) this.getSherlockActivity().findViewById(R.id.toggle_button1);
ToggleButton b2 = (ToggleButton) this.getSherlockActivity().findViewById(R.id.toggle_button2);
ToggleButton b3 = (ToggleButton) this.getSherlockActivity().findViewById(R.id.toggle_button3);
setListAdapter(list);
refresh();
}
public void refresh()
{
list = new SeparatedListAdapter(this.getSherlockActivity(), new Layout(R.layout.separated_list_adapter_two_text, R.id.two_text_title, R.id.two_text_desc));
refreshStats();
}
public void refreshStats()
{
//Omitted parsing code
list.addSection(new String("Hello world!!"));
setListAdapter(list);
}
}
However, when I use setListAdapter(list), the buttons are overwritten. They are visible before the app retrieves the data and parses it, but they are overwritten after I call setListAdapter. How can i fix this?
First, remove
android:orientation="horizontal"
from your root layout. RelativeLayout doesn't have an orientation property. Also, weight is for child elements of a LinearLayout and when you use it then you should assign the width of each child view to 0dp for horizontal orientation and height="0dp" for vertical orientation.
Then wrap your ToggleButtons in a LinearLayout, vertical or horizontal orientation, and give it the property
android:layout_alignParentTop="true"
then give your ListView the property
android:layout_below="#id/idOfLinearLayout"
So it may look something like
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/toggleLL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<ToggleButton
android:id="#+id/toggle_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="Apps"
android:textOn="Apps" />
<ToggleButton
android:id="#+id/toggle_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="VMs"
android:textOn="VMs" />
<ToggleButton
android:id="#+id/toggle_button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="Groups"
android:textOn="Groups" />
</LinearLayout>
<ListView
android:id="#+id/mylist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toggleLL" />
</RelativeLayout>
I also removed the RelativeLayout properties from the ToggleButtons since they are now wrapped in a LinearLayout. And you had a circular view error there with assigning the second ToggleButton to the right of itself which may have been a copy/paste error. Hope this helps.
Note that the default orientation for a LinearLayout is horizontal so leaving that property out will give you that effect.
Oh! I can not test your XML but I think that you need scrollbars! If the list is filled with a lot of entries, it can became bigger that the screen, making the buttons disappear because they are pushed up by the list. Try to add a scroll to the whole layout.
Something like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!-- Original layout here -->
</ScrollView>
</LinearLayout>
Of course, if you just put only one layout inside the scrollview, there is no need for the outer layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Original layout here -->
</ScrollView>

List view with buttons at the bottom of dialog theme activity keep overlapping

I am working on android project where I have an activity which is using the theme holo dialog.
Within the dialog I have a list view and what I want to have is at the bottom always on show a linear layout which contains two buttons next to each other. The list view is populated by retrieving data from the call log and populating the adapter of the list.
The problem I am having is the list view always shows on top taking up the whole dialogue with the buttons at the bottom, with the content of the list overlapping the buttons. I want the list to be within the space of the top of the dialogue to the top of the linear layout button group. Below is the code for the main content view. This layout is set using the setContentView in the onCreate method
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</ListView>
<LinearLayout android:id="#+id/call_log_select_host_button_group"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<Button android:id="#+id/call_log_select_btnCancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Block"/>
<Button android:id="#+id/call_log_select_btnBlock"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel" />
</LinearLayout>
</RelativeLayout>
I'm not sure if it makes any difference but just in case the below is how I am populating the list and setting the view.
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
CallInformation callInformation = (CallInformation)arrayList.get(position);
LayoutInflater inflator = (LayoutInflater)context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflator.inflate(R.layout.call_log_selection, parent, false);
ImageView imageView = (ImageView)rowView.findViewById(R.id.call_log_selector_image);
if (callInformation.type == android.provider.CallLog.Calls.INCOMING_TYPE)
{
imageView.setImageResource(android.R.drawable.sym_call_incoming);
}
else if (callInformation.type == android.provider.CallLog.Calls.OUTGOING_TYPE)
{
imageView.setImageResource(android.R.drawable.sym_call_outgoing);
}
else if (callInformation.type == android.provider.CallLog.Calls.MISSED_TYPE)
{
imageView.setImageResource(android.R.drawable.sym_call_missed);
}
CheckBox checkbox = (CheckBox)rowView.findViewById(R.id.call_log_selector_checkbox);
checkbox.setText(callInformation.content);
checkbox.setTag(callInformation.telephone);
return rowView;
}
}
The below code is the XML layout that is inflated by the adapter get view function
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView android:id="#+id/call_log_selector_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:layout_gravity="center"
android:src="#android:drawable/stat_sys_phone_call"/>
<CheckBox android:id="#+id/call_log_selector_checkbox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
Thanks for any help you can provide.
Try telling your ListView to stay above your LinearLayout
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/call_log_select_host_button_group> // Add this line here
</ListView>

LinearLayout as custom button, OnClickListener never called

I've been using the common Android Button with both icon (drawableTop) and text. It works really poorly if you want to have a non-standard size button, so I decided to make a custom button with a LinearLayout having the following layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/ButtonHoloDark"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:clickable="true"
android:focusable="true"
android:orientation="vertical" >
<ImageView
android:id="#+id/buttonIcon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:duplicateParentState="true" />
<TextView
android:id="#+id/buttonText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:duplicateParentState="true"
android:gravity="center"
android:textColor="#color/white" />
</LinearLayout>
The layout is used by a custom class:
public class CustomIconButton extends LinearLayout {
public CustomIconButton(Context context, AttributeSet attrs) {
super(context, attrs);
setAttributes(context, attrs);
LayoutInflater.from(context).inflate(R.layout.custom_icon_button, this, true);
}
...
But when I set an OnClickListener on my button in its parent layout it never gets called. I can only receive clicks if a set the listener to the ImageView and/or TextView. This leads to two possible effects when the button is clicked:
The click is inside the ImageView or the TextView. The click is registered ok, but the buttons state drawable doesn't change i.e. it doesn't appear depressed.
The click is inside the "empty area" of the button. The click is not registered, but the state drawable works ok.
Neither of these is feasible. I've played around with the following attributes on the LinearLayout or its children, but none really seem to have any effect whether true or false:
duplicateParentState
clickable
focusable
There doesn't seem to be any reasonable way to get the LinearLayout parent receive clicks instead of its children. I've seen some possible solutions overriding dispatchTouchEvent or onInterceptTouchEvent on the custom component itself, but that really seems like a big mess if I have to start analyzing touch events to identify proper clicks.
So OnClickListener on a LinearLayout with children = no go?
EDIT:
This is how I currently insert the buttons into my Fragment's main layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
<com.package.CustomIconButton
android:id="#+id/someButton"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
mynamespace:buttonIcon="#drawable/someIcon"
mynamespace:text="#string/str_someText" />
...
And the button is bound in the Fragment's code as follows:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.main, container, false);
View customButton = v.findViewById(R.id.goButton);
customButton.setOnClickListener(onClickListener);
...
Are you sure you set the listener on the correct LinearLayout(as you have two, the parent and the one from the inflated layout). Some time ago I made a similar component and the listener worked with no problems(I don't know what you have in those styles). The only difference was that I didn't add a (not needed) LinearLayout, instead I used the merge tag:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<ImageView
android:id="#+id/buttonIcon"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/buttonText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#color/white" />
</merge>
and set the style on the parent LinearLayout.
You can set a transparent child for your linear layout and set it's dimension fill_parent then register onClickListener for it,so when user click on it,it will respond.For example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#null" />
</LinearLayout>
onCreate():
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
iv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
System.out.println("CLICKED!");
}
});
}

Categories

Resources