I want to remove the container of my TextInputLayout on endDrawable click. I have multiple instances of these containers. I have 2 questions:
When I first initialise the onClick() method for each one in a for loop in onCreate(), do I have to use getId() to find the parent container of each TextInputLayout?
How can I use removeView(), getParent() (or otherwise) methods to remove the required view?
phoneNumberLayoutViews[v].setEndIconOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// Remove parent layout
}
});
Small Edit: I had to call getParent() multiple times to remove the parent I wanted. First, only the drawable was removed, then the TextInputEditText (I think), then the TextInputLayout, then the container.
((ViewGroup) view.getParent().getParent()
.getParent()
.getParent()
.getParent())
.setVisibility(View.GONE);
Related
I have a ConstraintLayout that contains a ViewPager and another widget, we could call "A". I would want to add a constraint between one ViewPager's widget (we could call "B") and "A". B is, of course, a widget that is contained, in reality, in a fragment (because ViewPagers work with fragments). Note that this fragment's layout is a ConstraintLayout too.
The fact is that I can't do it using XML, if I have correctly understood what I read&tried.
So I have tried to do it programatically using this code:
ConstraintSet constraintSet = new ConstraintSet();
ConstraintLayout constraintLayout = inflated.findViewById(R.id.fragment_home_constraint_layout);
constraintSet.connect(R.id.B, ConstraintSet.TOP, R.id.A, ConstraintSet.BOTTOM,0);
constraintSet.applyTo(constraintLayout);
R.id.fragment_home_constraint_layout is the constraint layout that contains the ViewPager and A.
So I'm trying to tell "Please constrain B, which is the ViewPager's item (nota: item = fragment) widget, to A, which is the widget of the layout which also contains the ViewPager".
The problem is: it does not work. No error, no crash. But it simply doesn't take effect. It's like if the constraint was not active, not set.
Why and how to do this?
Constraining two views having different parents is not possible
So I'm trying to tell "Please constrain B, which is the ViewPager's
item (nota: item = fragment) widget, to A, which is the widget of the
layout which also contains the ViewPager".
The above requirement wont be easy. You can still use some callbacks in your fragment. So whenever your widget in fragment chances its position, activity views should also move accordingly.
Example below should be a good start for you.
By clicking a button in Viewpager Fragment, the widget in the activity layout changes its position.
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
button = view.findViewById(R.id.buttonmove);
viewPager = getActivity().findViewById(R.id.vpPager);
activityButton = getActivity().findViewById(R.id.activity_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ConstraintLayout constraintLayout = (ConstraintLayout) getActivity().findViewById(R.id.fragment_home_constraint_layout);
ConstraintSet set = new ConstraintSet();
set.constrainWidth(R.id.activity_button, ConstraintSet.WRAP_CONTENT);
set.constrainHeight(R.id.activity_button, ConstraintSet.WRAP_CONTENT);
set.centerHorizontally(R.id.activity_button, R.id.fragment_home_constraint_layout);
set.connect(R.id.activity_button, ConstraintSet.TOP, R.id.vpPager, ConstraintSet.BOTTOM, 200);
set.applyTo(constraintLayout);
}
});
}
There is a Fragment named FragmentA that has a RelativeLayout with an ImageView behind it. (Say 4)Textviews are dynamically added to the rlParentView This layout resides inside a Fragment layout.
The Textviews are draggable inside the parent layout.
Another Fragment is loaded in the same activity and when FragmentA is reloaded, now the dynamically added textviews are lost so how can I retain the dynamically added TextViews with their text and other bounds.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.85"
android:layout_margin="5dp"
android:id="#+id/rlParentView">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/background_image" />
</RelativeLayout>
Dragable TextView are added dynamically like this:
View inflateLayout=mInflater.inflate(R.layout.text_drag_layout,mParentContainer,false);
TextView draggableView= (TextView) inflateLayout.findViewById(R.id.draggableView);
rlParentView.addView(inflateLayout);
draggableView.setText(Some_Text_here);
OnDragTouchListener listener=new OnDragTouchListener(draggableView, rlParentView,
new OnDragTouchListener.OnDragActionListener() {
#Override
public void onDragStart(View view) {
}
#Override
public void onDragEnd(View view) {
}
}
);
draggableView.setOnTouchListener(listener);
I haven't tried it, but here's an idea:
In onSaveInstanceState() of Fragment A, save the positions (and whetever else) of the TextViews inside their parent. Something like:
class ViewPositionInfo implements Serializable {
String text;
int xPositionInParent;
int yPositionInParent;
// ... other variables you need to store
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
List<ViewPositionInfo> positionInfos = new ArrayList<>();
// iterate over the views and add them inside the list
outState.putExtra("positions", positionInfos);
}
Then, when the fragment is re-created, read this information in onCreateView(), create TextViews with those attributes and add them to the parent layout.
The solution above has a drawback. When rotating the screen, the width / height will be different than before, so saving x and y positions of the the text views inside their parent might not be a good idea. You might need to save a relative position, i.e. a percentage. But first things first - make the simple case work (as explained above) and then think about this one.
I created a class that extends ActionBarActivity and displays a custom XML. That class is extended by almost all my activities.
I want to access an element of that custom XML from one of my activities. Let's say I want to change the background of item2 when I'm in Activity2.
In my activity's onCreate method, after setContentView, I tried:
View cView = getLayoutInflater().inflate(R.layout.custom_menu, null);
ImageButton rewards_link = (ImageButton) cView.findViewById(R.id.rewards_link);
rewards_link.setVisibility(View.GONE); // For test purpose
Even if the button id seems correct, the changes doesn't apply. Any ideas ?
If you are setting the custom view via getActionBar().setCustomView(R.layout.custom_menu); (or getSupportActionBar() for v21 of AppCompat), then you can access those views by using findViewById() directly as the view is part of your view hierarchy just like views added via setContentView():
ImageButton rewards_link = (ImageButton) findViewById(R.id.rewards_link);
rewards_link.setVisibility(View.GONE); // For test purpose
Use #getCustomView
View view =getSupportActionBar().getCustomView(); ImageButton imageButton =
(ImageButton)view.findViewById(R.id.action_bar_back); imageButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v){
// Your code here ...
}
});
I need to have an scroll with items together, and the selected item should expand a part down.
I am currently using a Gallery (I tried with viewflow and viewpager, but the items have much space between them), but I need to know how can I do this effect.
I have 2 ideas, but i don't know how can I implement it.
1) The expandable part is a LinearLayout with visibility=gone, and when the item is selected, this layout should be visible. (Gallery do not have "onItemSelectedListener")
2) Treat each element as a fragment (once I use a Viewpager that use this, https://github.com/mrleolink/SimpleInfiniteCarousel)
It does not necessarily have to be a gallery, any idea is welcome
I am working on an Activity.
Depends on the behavior that you want. Some questions can more than one item be expanded at a time? Do you want the views to be paged (snap into place) or smooth scroll them?
One Suggestion I have is to make a custom view for the individual cells. Then add them programmatically to a HorizontalScrollView Object.
HorizontalScrollView hsv = new HorizontalScrollView(activity);
LinearLayout hll = new LinearLayout(activity);
hll.setOrientation(LinearLayout.HORIZONTAL);
for(int i=0;i<items.length();i++){
hsv.addView(new CustomExpandView(item));
}
The CustomExpandView would be used for your cells and could be something like this...
public class CustomExpandView extends RelativeLayout implements OnClickListener {
MyActivity mActivity = null;
ImageView ivImage, ivOverImage;
RelativeLayout rlView;
public CustomExpandView(Context context) {
super(context);
initialize();
}
public CustomExpandView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public void initialize() {
mActivity = (MyActivity) this.getContext();
LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.custom_cell_expand, this, true);
//you can initialize subviews here
rlView = (RelativeLayout) getChildAt(0);
ivImage = (ImageView) rlView.getChildAt(0);
ivOverImage = (ImageView) rlView.getChildAt(1);
rlView.setOnFocusChangeListener(new OnFocusChangeListener(){
#Override
public void onFocusChange(View v, boolean hasFocus) {
LinearLayout expand = v.findViewById(R.id.view_i_want_to_expand);
if(hasFocus)
expand.setVisibility(View.VISIBLE);
else
expand.setVisibility(View.GONE);
}
});
}
You gave the answer yourself. You can use a ViewPager, with fragments, and have an animation to extend the lower part of the window. Depends on whether you want the windows to be full screen or not. A viewpager doesn't necessarily need fragments, you can use ordinary views, and an appropriate adapter. Just play with it and see which solution you like most.
Next time, just create the code and the app, and ask a much more specific question, with code to illustrate the issue you're experiencing.
You could simply define a TableView with just one TableRow (or as many as you need) and set a onClickListener for each of those Views inside the TableRow, which would make that on any click, the selected View would expand itself.
I don't know whether you'll have a static number of Views inside that row or you'll construct them dynamically, but this should work for any of them, the real "work" here about populating that row.
Once you have your row of Views, simply declare an onClickListener() on each of them. For example, this should be enough:
OnClickListener myListener = new OnClickListener() {
#Override
public void onClick(final View v) {
v.setVisibility(View.VISIBLE);
}
};
And as the onClick event for all of your items inside the TableRow:
for (View v : myTableRowViews)
v.setOnClickListener(myListener);
This has a disadvantage: You can know which View has been clicked for selection, but natively you cannot know which has been deselected, so you'll need to keep track of the last selected tab declaring a class-wide variable and setting it each time onClick() is fired, so your listener will become something like this:
// In your class declare a variable like this
View lastSelected = null;
OnClickListener myListener = new OnClickListener() {
#Override
public void onClick(final View v) {
if (lastSelected != null)
lastSelected.setVisibility(View.GONE);
v.setVisibility(View.VISIBLE);
lastSelected = v;
}
};
Additionally, you can set an animation to the effect to make it more attractive, but mainly this is the idea.
One last thing: To make it work this way you'll need to set the layout_height of both your TableRow and the View items inside, so it may expand afterwards when you set the additional part as visible. Also, to make it look good all of your Views will have to be the same height (both in the reduced and extended state).
I am using a Linear Layout inside of a dialog, and have some TextViews inside that layout that I would also like to change color based on the "pressed" state of the Layout that is their parent. They have a state-list for what color they should be, but it seems that when the layout is clicked, the Views beneath it are not given that "clicked" state.
How could I make the TextViews change color when their parent layout is clicked?
The easiest way is just to pass the event down into whatever the child views are. You can extend TextView and add a method that you can call from the Layout's onclick handler.
class MyTV extends TextView{
public MyTV(Context c){
//constructor gets context in case you want to make instances from code rather than XML
}
public doSomethingToMe(){
//do stuff to this View from outside
}
}
then in your Activity...
public void layoutClicked(View v){ //call this from your layout click
((MyTV)findViewById(R.id.myTV1)).doSomethingToMe();
}