I'm dealing with a problem, hope you can help me.
I want to disable all childs inside a scrollview, but i want to be able to scroll and also maintain the appearance of the views the same as if they where enabled.
My layout:
<ScrollView
android:id="#+id/newEventScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/eventLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<com.xw.repo.BubbleSeekBar
android:id="#+id/durationBubble"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:bsb_bubble_color="#color/colorPrimaryDarker"
app:bsb_bubble_text_color="#color/colorWhite"
app:bsb_max="12"
app:bsb_min="0"
app:bsb_progress="0"
app:bsb_second_track_color="#color/colorPrimaryDarker"
app:bsb_section_count="2"
app:bsb_section_text_position="below_section_mark"
app:bsb_show_progress_in_float="true"
app:bsb_show_section_mark="true"
app:bsb_show_section_text="true"
app:bsb_show_thumb_text="false"
app:bsb_thumb_radius="8dp"
app:bsb_track_color="#color/colorWhite" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="#string/hearingLoss" />
<android.support.v7.widget.SwitchCompat
android:id="#+id/hearingLossSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textColorHint="#color/colorPrimaryDark"
android:theme="#style/SCBSwitch" />
</LinearLayout>
</RelativeLayout>
</ScrollView>
What i need is to don't let the user to change any view, like switch or seekBar.
I've tried this things:
Disable nested views, scroll working but disable appearance that i dont like.
private void disableEnableControls(boolean enable, ViewGroup vg){
for (int i = 0; i < vg.getChildCount(); i++){
View child = vg.getChildAt(i);
child.setEnabled(enable);
if (child instanceof ViewGroup){
disableEnableControls(enable, (ViewGroup)child);
}
}
}
Do nothing on OnClickListener, scroll not working
private void disableEnableControls(boolean enable, ViewGroup vg){
for (int i = 0; i < vg.getChildCount(); i++){
View child = vg.getChildAt(i);
child.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
if (child instanceof ViewGroup){
disableEnableControls(enable, (ViewGroup)child);
}
}
}
Create another view inside scrollview and setting visible when i want, scroll not working.
Any suggestion on how to do this?
Thanks in advance.
If you want to disable a view (which I am assuming you are talking about views such as those with click listeners or checkboxes,...), you can simply disable the click listeners (if that is what you want) in your java code: either set an if condition in your listener callback method, or set the clickable feature of the view to false.
Related
I have a list(container) with couple views I'd like to hide and show again when collapse/expand button is clicked.
No problem so far, now i want to animate hiding and showing of my nested views, i didn't want to complicate with animations and i went with default ones.
That is why i added android:animateLayoutChanges="true" to container layout, this works great when showing/expanding views, but looks terrible when hiding/collapsing views.
Is there any particular reason behind this behavior?
Code and example below:
Code
container layout
<LinearLayout
android:id="#+id/izdelek_podrponud_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:animateLayoutChanges="true"
>
</LinearLayout>
child view layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/spacing_medium"
android:paddingBottom="#dimen/spacing_medium"
android:gravity="center_vertical">
<View
android:layout_width="5dp"
android:layout_height="5dp"
android:background="#color/colorPrimary"/>
<TextView
android:id="#+id/row_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/spacing_small"
android:textSize="#dimen/font_size_60px"
android:textColor="#color/black"/>
</LinearLayout>
And this is how i handle showing and hiding;
private void showViews(LinearLayout container, int visible, boolean show) {
if (container.getChildCount() > visible) {
for (int i = visible; i < container.getChildCount(); i++) {
if (show) {
container.getChildAt(i).setVisibility(View.VISIBLE);
} else {
container.getChildAt(i).setVisibility(View.GONE);
}
}
}
}
I have this XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/button_bar"
style="?android:buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#color/md_green_400" />
<Button
android:id="#+id/action_button"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#color/md_green_400" />
</LinearLayout>
It´s just a buttonBar with two borderless buttons. It works. However, I don't want that, I need to inflate these buttons from a JSONArray. So I did this:
for (int b = 0; b < buttons.length(); b++) {
final JSONObject button = buttons.getJSONObject(b);
LinearLayout buttonBar = (LinearLayout) child.findViewById(R.id.button_bar);
View buttonChild = getLayoutInflater().inflate(R.layout.flat_button, null);
Button action = (Button) buttonChild.findViewById(R.id.action_button);
action.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {}
});
action.setText(button.getString("descricao"));
action.setTextColor(Color.parseColor(button.getString("text_color")));
buttonBar.addView(buttonChild);
}
It works too, but the buttons get a left alignment. I want they justified.
Why it works when I let them fixed but not when I inflate them?
OBS: The "button_bar" is A XML just with a LinearLayout and the "ActionButton" is just a XML with a Button.
This is the root of your problem:
View buttonChild = getLayoutInflater().inflate(R.layout.flat_button, null);
If you don't provide the parent view to the inflate() method, any LayoutParams attributes (e.g. layout_gravity) will be discarded since the parent is the one to interpret those attributes.
You can fix this by changing it to:
View buttonChild = getLayoutInflater().inflate(
R.layout.flat_button, buttonBar, false);
Which will give it the parent you're attaching it to, but not attach it to the hierarchy yet (you do that below with addView()).
I have layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/exchangeView">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#fff000"
android:gravity="center"
android:text="Sticker 1"
android:textColor="#372c24"
android:textSize="20dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:id="#+id/next">
<Button
android:id="#+id/btn_next"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_alignParentBottom="true"
android:text="Next" />
</LinearLayout>
</LinearLayout>
</ScrollView>
and related code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.exchange);
layout = (View) findViewById(R.id.exchangeView);
}
next thing I want to do is to get all children elements in this layout with Id=exchangeView, but when I type layout.getChildCount() android studio IDE compiler says:
Cannot resolve method 'getChildCount()'
However, if I put breakpoint on line where I assign layout a value, then if I evaluate expression I can execute method layout.getChildCount()
All I want to do is to execute layout.getChildCount() during runtime.
Thanks in advance!
Change this line
layout = (View) findViewById(R.id.exchangeView);
to
layout = (LinearLayout) findViewById(R.id.exchangeView);
I am assuming you have declared the variable layout as
View layout;
If so, change that to
LinearLayout layout;
The View class doesn't have the method getChildCount(), it is a method in the ViewGroup class. LinearLayout extends ViewGroup, and hence has access to it. View does not. This is related to polymorphism, which I suggest you look up.
Cheers.
You can try to use getChildCount() and also getChildAt() like this may be
int childcount = ll.getChildCount();
for (int i=0; i < childcount; i++){
View v = ll.getChildAt(i);
}
Try this:
LinearLayout layout = setupLayout();
int count = layout.getChildCount();
View v = null;
for(int i=0; i<count; i++) {
v = layout.getChildAt(i);
//do something with your child element
}
So I have an XML layout1 which is just a LinearLayout with three text views. I also have another XML layout2 with ScrollView and a LinearLayout inside it. I'm using this for loop to create several of the layout2 inside the LinearLayout of the ScrollView. It's working fine but I want to be able to set the text of each of the TextViews within the for loop. I'm not sure how to access these TextViews as I can only set one id within the XML file, will that not cause problems if I tried to access their id inside the for loop?
private void setUpResults() {
for (int i = 1; i < totalQuestions; i++) {
parent.addView(LayoutInflater.from(getBaseContext()).inflate(
R.layout.result_block, null));
}
}
Here is the result_block xml file (layout1) :
<?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:id="#+id/layoutSelectedAnswer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/border"
android:orientation="horizontal"
android:paddingBottom="#dimen/option_padding_bottom"
android:paddingTop="#dimen/option_padding_top" >
<TextView
android:id="#+id/tvOptionALabel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="#string/option_a"
android:textColor="#color/white"
android:textSize="#dimen/option_text_size" />
<TextView
android:id="#+id/tvSelectedAnswer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="#string/option"
android:textColor="#color/white"
android:textSize="#dimen/option_text_size" />
</LinearLayout>
<LinearLayout
android:id="#+id/layoutCorrectAnswer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/border"
android:orientation="horizontal"
android:paddingBottom="#dimen/option_padding_bottom"
android:paddingTop="#dimen/option_padding_top" >
<TextView
android:id="#+id/tvOptionBLabel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="#string/option_b"
android:textColor="#color/white"
android:textSize="#dimen/option_text_size" />
<TextView
android:id="#+id/tvCorrectAnswer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="#string/option"
android:textColor="#color/white"
android:textSize="#dimen/option_text_size" />
</LinearLayout>
</LinearLayout>
Let's say I wanted to set the TextView with the id as tvCorrectAnswer to a different String value in each loop, how should I access it?
Sure, you can do it like this:
private void setUpResults () {
LayoutInflater i = LayoutInflater.from(getBaseContext());
for (int i = 1 /* should be zero? */; i < totalQuestions; i++) {
View view = i.inflate(R.layout.result_block, parent, false);
TextView correctAnswer = (TextView) view.findViewById(R.id.tvSelectedAnswer);
correctAnswer.setText("My Answer Text");
parent.addView(view);
}
}
The key is, inflate using the parent as the container, but don't attach it (the false parameter). Then you'll get a reference to the inflated view, which you can then directly reference to do your findViewById() calls (which will limit the search to that particular ViewGroup). Then add it to the parent and continue to the next item.
Once you have added all your views in your ViewGroup you can use ViewGroup.getChildAt(int) to get a one of the views you have inserted. Once you get one of the views you can access any of its inner views. Something like this.
for(int i = 0; i < parentView.getChildCount();++i) {
View v = parentView.getChildAt(i);
Textview tv = (TextView) v.findViewById(R.id.tvOptionALabel2);
//And so on...
}
Is it possible to use a OnItemClickListener on a ListView when the Items layout has a clickable/editable widget (RadioButton,EditText, or CheckBox)?
You might want to take a look at this issue. Having a focusable item in a row of a ListView causes the OnItemClickListener NOT to be invoked. However, that does not mean you cannot have focusable/clickable items in a row, there are some workarounds like this one.
Also, you can take a look at the Call Logs screen. It has a ListView with clickable item(the call icon on the right).
See Source code here
Quoting comment #31 in the link mentioned by Samuh (which solved the problem for me):
In fact you can add it to the layout XML (if inflated by one): android:descendantFocusability="blocksDescendants".
Adding here JIC that webpage is down in the future.
If any row item of list contains focusable or clickable view then OnItemClickListener won't work.
row item must be having param like android:descendantFocusability="blocksDescendants"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:descendantFocusability="blocksDescendants"
android:gravity="center_vertical" >
// your other widgets here
</LinearLayout>
Tried many complex solutions, but this was the simplest one that worked:
Just use android:focusable="false" as in:
<CheckBox
android:id="#+id/fav_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false" />
Two best solution
Add android:descendantFocusability="beforeDescendants" to listView
in xml OR
Set given two attributes to false
like
android:focusable="false"
android:focusableInTouchMode="false"
Then it will handle the listView row item child(Button,EditText etc) events instead of listView.setOnItemClick .
I fixed my problem different , in my item I have more than one LinearLayout
so if you give id to your linearayout and setOnclickListener in adapter class it will work, only original effect of touching will dissapear.
but this link Making a LinearLayout act like an Button is usefull to make linearlaout act like button on click
item
<?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"
android:layout_marginTop="10dp">
<TextView
android:id="#+id/txt_item_followers_name"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center|start"
android:paddingLeft="15dp"
android:text="Ali"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/imageView"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_alignParentStart="true"
android:layout_below="#+id/txt_item_followers_name"
android:layout_marginLeft="10dp"
android:src="#drawable/puan_icon" />
<TextView
android:id="#+id/txt_item_followers_mark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView"
android:layout_toEndOf="#+id/imageView"
android:background="#color/red_400"
android:paddingLeft="10dp"
android:text="25.5"
android:textAppearance="?android:attr/textAppearanceSmall" />
<LinearLayout
android:id="#+id/linear_one"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentTop="true"
android:layout_toEndOf="#+id/txt_item_followers_name"
android:background="#color/red_400"
android:orientation="vertical">
<ImageView
android:id="#+id/btn_item_followers_2b_follow"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_marginLeft="10dp"
android:src="#drawable/follow_buton" />
</LinearLayout>
</RelativeLayout>
inside getView method
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
View view = convertView;
if (convertView == null)
view = inflater.inflate(R.layout.deneme, null);
final Followers2 myObj = myList.get(position);
LinearLayout linear_one = (LinearLayout) view.findViewById(R.id.linear_one); // HERE WE DOMUNİCATE IT
linear_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(parentActivity, "One Two", Toast.LENGTH_SHORT).show();
}
});
TextView name = (TextView) view.findViewById(R.id.txt_item_followers_name);
TextView mark = (TextView) view.findViewById(R.id.txt_item_followers_mark);
final ImageView btn_follow = (ImageView) view.findViewById(R.id.btn_item_followers_2b_follow);
name.setText(myObj.getName());
mark.setText(myObj.getScore());
/* if (myObj.isFollow() == true) {
btn_follow.setImageResource(R.drawable.following_buton);
} else {
btn_follow.setImageResource(R.drawable.follow_buton);
}
btn_follow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Followers2 myObj = myList.get(position);
if (myObj.isFollow() == true) {
btn_follow.setImageResource(R.drawable.following_buton);
} else {
btn_follow.setImageResource(R.drawable.follow_buton);
}
}
});*/
return view;
}