Note: These are randomly generated addresses
Hey Guys, Learning Xamarin and I am trying to scroll my Frame Layour down and reveal a search bar for my list view. Here is what is happening:
I color coded my layouts to see if the sizes where a problem, but I dont think they are since my orange layout is plenty big to hold my two entries. Am I using the wrong layouts for this kind of application? I would appreciate any help!
Here is my translation code:
frameLayout.Animate().TranslationYBy(editSearch.Height).SetDuration(500).Start();
And my layout file:
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipeLayout">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="100dp"
android:id="#+id/frameLayoutParent"
android:background="#android:color/holo_green_dark">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frameLayout"
android:background="#android:color/holo_green_light">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="300dp"
android:background="#android:color/holo_orange_light">
<Button
android:text="Add New Address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/addNewAddress"
android:maxHeight="20dp" />
</LinearLayout>
<ListView
android:paddingTop="50dp"
android:minWidth="25px"
android:minHeight="300dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/myListView"
android:maxHeight="300dp"/>
</FrameLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editSearch"
android:hint="Search ZipCodes"
android:textColor="#000"/>
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
EDIT:
Here is my OnOptionsItemSelected Code, where my animation is triggered.
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.action_search:
//search icon has been clicked
if (isAnimating)
return true;
else
{
if (animateBool)
{
//list view is up
animation anim = new animation(myListView, myListView.Height - editSearch.Height);
anim.Duration = 500;
myListView.StartAnimation(anim);
anim.AnimationStart += Anim_AnimationStartDown; //listener for when animation has started
anim.AnimationEnd += Anim_AnimationEndDown;
classSwipeRefresh.Animate().TranslationYBy(editSearch.Height).SetDuration(500).Start();
}
else
{
animation anim = new animation(myListView, myListView.Height + editSearch.Height);
anim.Duration = 500;
myListView.StartAnimation(anim);
anim.AnimationStart += Anim_AnimationStartUp; //listener for when animation has started
anim.AnimationEnd += Anim_AnimationEndUp;
classSwipeRefresh.Animate().TranslationYBy(-editSearch.Height).SetDuration(500).Start();
}
animateBool = !animateBool;
return true;
}
default:
return base.OnOptionsItemSelected(item);
}
}
Learning Xamarin and I am trying to scroll my Frame Layour down and reveal a search bar for my list view. Here is what is happening:
I use your code to test, but I have no problem when translating by Y in SwipeRefreshLayout__Refresh event.
public class MainActivity : AppCompatActivity
{
string[] items;
ListView listview1;
SwipeRefreshLayout swiplayout;
FrameLayout framelayout;
EditText edittext;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
listview1 = FindViewById<ListView>(Resource.Id.myListView);
swiplayout = FindViewById<SwipeRefreshLayout>(Resource.Id.swipeLayout);
framelayout = FindViewById<FrameLayout>(Resource.Id.frameLayout);
edittext = FindViewById<EditText>(Resource.Id.editSearch);
swiplayout.Refresh += Swiplayout_Refresh;
items = new string[] { "Vegetables", "Fruits", "Flower Buds", "Legumes", "Bulbs", "Tubers" };
listview1.Adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, items);
}
private void Swiplayout_Refresh(object sender, EventArgs e)
{
framelayout.Animate().TranslationYBy(edittext.Height).SetDuration(500).Start();
}
}
This is my screenshot:
If you want to filter ListView, I suggest you can use SearchView in Toolbar to filter listview data, please take a look this sample:
https://github.com/Cheesebaron/SearchView-Sample/tree/master/SearchViewSample
Related
I am very new to Leanback Libraries. I want to develop Android TV home screen, where the CustomHeaderItem will be on left side and for each HeaderItem there will be one ListRow and instead of BrowseFragment, i want to render whole things on VerticalGridView. Like below picture.
To achiveve this, i tried to keep an ImageView with HorizontalGridView and both views i rendered inside VerticalGridView.
While doing so, the focus is moving from imageView to respective HorizontalGridView on clicking on Right dpad Key which is expected behaviour but coming back from respective HorizontalGridView to respective ImageView is not happening.
row_grid_view_renderer.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:lb="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/header_icon"
android:layout_width="300dp"
android:paddingBottom="50dp"
android:layout_height="150dp"
android:layout_gravity="center"
android:gravity="center"
android:focusable="true"
android:layout_weight="1"
android:clickable="true"
android:background="#drawable/selector_bg_card"
android:focusableInTouchMode="true" />
<androidx.leanback.widget.HorizontalGridView
android:id="#+id/row_grid_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:layout_gravity="center"
android:focusableInTouchMode="true"
android:layout_weight="2"
lb:horizontalMargin="12dip"
lb:verticalMargin="24dip"
lb:numberOfRows="3"
lb:rowHeight="150dip" />
</LinearLayout>
main_grid_view_rendere.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.leanback.widget.VerticalGridView
android:id="#+id/parent_grid_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Below i am overriding the createRowViewHolder() method of ListRowPresenter class to set the imageView and HorizontalGridView.
public class CustomListRowPresenter extends ListRowPresenter {
private static final String TAG = CustomListRowPresenter.class.getSimpleName();
private static final boolean DEBUG = true;
private CustomListRowView rowView;
public CustomListRowPresenter() {
super();
}
public RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) {
rowView = new CustomListRowView(parent.getContext(),null,-1);
rowView.getImageView().setImageResource(R.drawable.ic_blur_on_black_24dp);
return new ViewHolder(rowView, rowView.getRowGridView() , this);
}
And here is my MainActivity class which is rendering ImageView and HorizontalGridView inside main_grid_view(which is holding VerticalGridView).
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_grid_view);
mVerticalGridView = (VerticalGridView) findViewById(R.id.parent_grid_view);
loadRows();
}
private void loadRows() {
cardPresenter = new CardPresenter();
rowsAdapter = new ArrayObjectAdapter(new CustomListRowPresenter());
List<Movie> list = MovieList.setupMovies();
int i;
for (i = 0; i < NUM_ROWS; i++) {
if (i != 0) {
Collections.shuffle(list);
}
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
for (int j = 0; j < NUM_COLS; j++) {
listRowAdapter.add(list.get(j % 5));
}
HeaderItem header = new HeaderItem(i, MovieList.MOVIE_CATEGORY[i]);
rowsAdapter.add(new CustomListRow(header, listRowAdapter));
}
ItemBridgeAdapter itemBridgeAdapter = new ItemBridgeAdapter(rowsAdapter);
mVerticalGridView.setAdapter(itemBridgeAdapter);
}
I want to get the focus in both respective View while pressing Right and Left key of Dpad.
How i will achieve the above scenario or where i am going wrong ?
And also, How to stop header transition inside BrowseFragment ?
Thanks in advance :)
I have created a DrawerLayout with a right side drawer. So far, so good. Now, there's one menu item which, when clicked opens a pop-out menu with 5 different options (see screenshot). When one of the options is clicked the icon in the main menu should get swapped for the icon that I just clicked and then the main menu should close. However, I have not been able to create that behaviour. Currently when I try to click one of the options in the pop-out menu the following happens:
1. The main menu (the drawer) closes.
2. Only if I click the desired option again the icon in the main menu gets swapped.
As far as I understand this it is the default behaviour of a drawer within a DrawerView to be closed as soon as I click somewhere in the screen. I have tried to work around it by setting the lock mode:
myDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, Gravity.END)
... but no luck. The drawer closes as soon as I try to click one of the items in the pop-out.
Is it even possible to achieve what I want in a DrawerLayout?
Here's my code:
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.videosc2.activities.VideOSCMainActivity">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/camera_downscaled"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:antialias="false"
android:contentDescription="#string/preview_image_content_description"
android:scaleType="fitXY"/>
</FrameLayout>
<!-- The navigation drawer that comes from the right (layout_gravity:end) -->
<ListView
android:id="#+id/drawer"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|end"
android:background="#99000000"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="10dp"
app:itemTextColor="#android:color/white"/>
</android.support.v4.widget.DrawerLayout>
drawer_item.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tool"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator"
android:contentDescription="#string/a_tools_menu_item"
android:gravity="center_vertical"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="8dp"/>
color_mode_panel.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/color_mode_panel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="60dp"
android:layout_marginRight="60dp"
android:layout_marginTop="100dp"
android:background="#99000000"
android:clickable="true"
android:orientation="horizontal">
<ImageButton
android:id="#+id/mode_rgb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_rgb"
android:padding="8dp"
android:src="#drawable/rgb"/>
<ImageButton
android:id="#+id/mode_rgb_inv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:clickable="true"
android:contentDescription="#string/color_mode_rgb_neg"
android:padding="8dp"
android:src="#drawable/rgb_inv"/>
<ImageButton
android:id="#+id/mode_r"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_r"
android:padding="8dp"
android:src="#drawable/r"/>
<ImageButton
android:id="#+id/mode_g"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_g"
android:padding="8dp"
android:src="#drawable/g"/>
<ImageButton
android:id="#+id/mode_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_b"
android:padding="8dp"
android:src="#drawable/b"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
static final String TAG = "MainActivity";
View camView;
public static Point dimensions;
private DrawerLayout toolsDrawerLayout;
private FrameLayout mainFrame;
private ActionBarDrawerToggle drawerToggle;
protected ArrayList<View> uiElements = new ArrayList<>();
// is device currently sending OSC?
public boolean isPlaying = false;
// is flashlight on?
public boolean isTorchOn = false;
// don't create more than one color mode panel
private boolean isColorModePanelOpen = false;
public Fragment cameraPreview;
Camera camera;
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
final FragmentManager fragmentManager = getFragmentManager();
if (findViewById(R.id.camera_preview) != null) {
camView = findViewById(R.id.camera_preview);
if (savedInstanceState != null) return;
cameraPreview = new VideOSCCameraFragment();
fragmentManager.beginTransaction()
.replace(R.id.camera_preview, cameraPreview, "CamPreview")
.commit();
}
TypedArray tools = getResources().obtainTypedArray(drawer_icons_id);
toolsDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
toolsDrawerLayout.setScrimColor(Color.TRANSPARENT);
// FIXME: touches seem to get swallowed by the DrawerLayout first
final ListView toolsDrawerList = (ListView) findViewById(R.id.drawer);
List<BitmapDrawable> toolsList = new ArrayList<>();
for (int i = 0; i < tools.length(); i++) {
toolsList.add((BitmapDrawable) tools.getDrawable(i));
}
// set the drawer menu in a custom Adapter
toolsDrawerList.setAdapter(new ToolsMenuAdapter(this, R.layout.drawer_item, R.id.tool, toolsList));
tools.recycle();
toolsDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BitmapDrawable img;
final ImageView imgView = (ImageView) view.findViewById(R.id.tool);
Context context = getApplicationContext();
// we can not use 'cameraPreview' to retrieve the 'mCamera' object
VideOSCCameraFragment camPreview = (VideOSCCameraFragment) fragmentManager.findFragmentByTag("CamPreview");
camera = camPreview.mCamera;
LayoutInflater inflater = getLayoutInflater();
switch (i) {
// ... other cases...
case 2:
if (!isColorModePanelOpen) {
int y = (int) view.getY();
// create pop-out
final View modePanel = inflater.inflate(R.layout.color_mode_panel, (FrameLayout) camView, true);
isColorModePanelOpen = true;
// try to lock the main menu drawer - didn't work for me
toolsDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, toolsDrawerList);
final View modePanelInner = modePanel.findViewById(R.id.color_mode_panel);
// set the vertical position of the pop-out
ActivityHelpers.setMargins(modePanelInner, 0, y, 0, 0);
// set actions for each item in the pop-out
for (int k = 0; k < ((ViewGroup) modePanelInner).getChildCount(); k++) {
final Context iContext = context;
View button = ((ViewGroup) modePanelInner).getChildAt(k);
button.setOnClickListener(new View.OnClickListener() {
#Override
// FIXME: touches seem to get swallowed by the DrawerLayout first
public void onClick(View view) {
switch (view.getId()) {
case R.id.mode_rgb:
Log.d(TAG, "rgb");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb));
break;
case R.id.mode_rgb_inv:
Log.d(TAG, "rgb inverted");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb_inv));
break;
case R.id.mode_r:
Log.d(TAG, "red");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.r));
break;
case R.id.mode_g:
Log.d(TAG, "green");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.g));
break;
case R.id.mode_b:
Log.d(TAG, "blue");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.b));
break;
default:
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb));
}
// remove the pop-out
((ViewGroup) modePanelInner.getParent()).removeView(modePanelInner);
isColorModePanelOpen = false;
// unlock the drawer again
toolsDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.END);
// now the drawer should finally get closed
toolsDrawerLayout.closeDrawer(Gravity.END);
}
});
}
}
break;
// ... other cases ...
}
});
// open drawer on application start
toolsDrawerLayout.openDrawer(Gravity.END);
}
}
}
Edit:
I found this post that offered me a simple way of preventing my pop-out from being closed by adding the following to my MainActivity.java:
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
// We only want to intercept MotionEvent.ACTION_UP if the pop-out is present
return !(isColorModePanelOpen && event.getAction() == MotionEvent.ACTION_UP) && super.dispatchTouchEvent(event);
}
That worked in so far as the drawer is not being closed immediately when trying to click one of the buttons in the pop-out. Unfortunately, the buttons don't accept clicks (resp. touches with an event action MotionEvent.ACTION_DOWN) either. It seems, as long as the drawer isn't closed again, the whole screen is being blocked from any user interaction.
Can anyone confirm my suspicion? (or prove me wrong)
Thanks
Try this code in onResume() of your Activity
if(condition)
{
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
}
else
{
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
I found many similar questions on StackOverflow, but can't seem to figure out this issue.
I'm trying to bind an ObservableCollection to a ListView so that when the contents of the collection change the ListView will automatically update. Unfortunately, when elements are added to the collection (via button click), the ListView isn't being updated. How can I make the ListView reflect the current contents of the collection?
Note: It seems that if I force layout with listView.RequestLayout(); the listView will contain the correct number of items. However, it won't necessarily contain the right items. For example, if I delete the first item and add a new one at the end, forcing a layout has no effect. If I force the layout after deleting the first item, then again after adding one at the end, the contents are correct.
Activity code
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
ObservableCollection<UserTask> allTasksCollection = new ObservableCollection<UserTask>();
while(count < 6)
{
allTasksCollection.Add(new UserTask("Task number " + count));
count++;
}
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Bind listview to all tasks
ListView listView = FindViewById<ListView>(Resource.Id.allTasksListView);
UserTaskListAdapter adapter = new UserTaskListAdapter(this, allTasksCollection);
listView.Adapter = adapter;
// Button click should add a new task and remove the first task.
Button button = FindViewById<Button>(Resource.Id.myButton);
button.Click += delegate {
allTasksCollection.Add(new UserTask("Task number " + count));
button.Text = string.Format("{0} tasks!", count++);
};
}
}
Adapter
public class UserTaskListAdapter : BaseAdapter<UserTask>
{
Activity context;
ObservableCollection<UserTask> list;
public UserTaskListAdapter(Activity _context, ObservableCollection<UserTask> _list)
: base()
{
this.context = _context;
this.list = _list;
}
public override int Count
{
get { return list.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override UserTask this[int index]
{
get { return list[index]; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
view = context.LayoutInflater.Inflate(Resource.Layout.UserTaskRowItem, parent, false);
UserTask item = this[position];
view.FindViewById<TextView>(Resource.Id.Title).Text = item.Name;
return view;
}
}
Main XAML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/rootLayout">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/allTasksContainer">
<Button
android:id="#+id/myButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/allTasksListView" />
</LinearLayout>
</LinearLayout>
ListItem XAML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/linearLayoutHorizontal">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/CheckboxContainer">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/checkboxSelect" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/TextContainer">
<TextView
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/Title" />
<TextView
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/DueDate" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Try to call NotifyDataSetChanged() on your adapter after updating its items, AFAIK ListView in Android doesn't observe the changes on your ObservableCollection:
Try this code:
button.Click += delegate {
allTasksCollection.Add(new UserTask("Task number " + count));
button.Text = string.Format("{0} tasks!", count++);
adapter.NotifyDataSetChanged();
};
You can also try to add a litener to your ObservableCollection, in your adapter, change the constructor to this:
this.list.CollectionChanged += (sender,args) => { NotifyDataSetChanged(); };
Take a look at the INotifyPropertyChanged interface. It will warn the listview that variables within an object within the listview have changed.
https://developer.xamarin.com/guides/xamarin-forms/xaml/xaml-basics/data_bindings_to_mvvm/
Edit: misread your question. My bad.
I am using a SwipeRefreshLayout and an EnhancedListView to combine them like GMAIL-App. When I start to swipe horizontal I am still be able to swipe vertical. In this case the animation from EnhancedListView stuck and do not reset or swipe till the end if I do not complete the vertical (SwipeRefreshLayout) swipe.
I can see, that first pull to refresh and then swipeToDismiss does not work. Only first swipe and then refresh. So i guess it is about beeing a parent element.
Possible Solution i thought about:
Check for horizontal scrolling and disable SwipeRefreshLayout with swipeL.setEnabled(false); When finished swipeL.setEnabled(true); But I can not find where to disable and enable it.
My Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="#0A756E"
android:gravity="center" >
<LinearLayout
android:id="#+id/ll_archiv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/greenbox" >
<TextView
android:id="#+id/tv_archiv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:text="#string/archiv"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#fff" />
</LinearLayout>
</RelativeLayout>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<de.android.voucheroo.utils.EnhancedListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/footer"
android:layout_alignParentTop="true"
android:descendantFocusability="blocksDescendants" >
</de.android.voucheroo.utils.EnhancedListView>
</android.support.v4.widget.SwipeRefreshLayout>
My Code:
swipeL = (SwipeRefreshLayout) getActivity().findViewById(
R.id.swipe_container);
ll_archiv = (LinearLayout) getActivity().findViewById(R.id.ll_archiv);
tv_archiv = (TextView) getActivity().findViewById(R.id.tv_archiv);
elv = (EnhancedListView) getActivity().findViewById(android.R.id.list);
elv.setDismissCallback(new OnDismissCallback() {
#Override
public Undoable onDismiss(EnhancedListView listView,
final int position) {
try {
final Object vouch = voucher.get(position);
voucher.remove(position);
adapter.notifyDataSetChanged();
return new EnhancedListView.Undoable() {
#Override
public void undo() {
voucher.add(position, vouch);
adapter.notifyDataSetChanged();
}
// Return a string for your item
#Override
public String getTitle() {
return "foo";
}
// Delete item completely from your persistent storage
#Override
public void discard() {
[...];
}
};
} catch (Exception e) {
Log.w("ELV_EXCEPTION", e.getMessage());
e.getStackTrace();
return null;
}
}
});
swipeL.setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
[...]
swipeL.setRefreshing(false);
}
});
// Handler
elv.enableSwipeToDismiss();
elv.setSwipingLayout(R.id.ll_parent);
elv.setUndoStyle(UndoStyle.MULTILEVEL_POPUP);
Nowsaday I know the answer of my own question. It is not a problem with my code, it is a problem with SwipeRefreshView.
There is a similar question with the same Problem I found here: SO-Answer
I have a layout with a top bar container and a content container. When clicking on a button in the top bar, a vertical menu is displayed using an animation. My minSdkVersion is 9.
This works well when I start the app and I still haven't clicked a menu button (i.e. the content fragment has not changed), but as soon as I have clicked an option (and then replace the fragment in the content_container), the vertical menu behaves erratically. The click event of the menu btn is properly triggered, but the vertical menu is not always shown (but sometimes it is...). However, when I click the button and then touch the screen, the animation (show or hide the menu) starts.
I guess it has something to do with the vertical menu overlapping the content fragment, and then replacing the content fragment modify it in some way, but I can't find any solution.
Anybody can help?
top bar fragment
#Override
public void onActivityCreated (Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
toggleMenu(0);
Button btn_menu = (Button) getView().findViewById(R.id.btn_menu);
btn_menu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mVerticalMenu.setVisibility(View.VISIBLE);
toggleMenu(1000);
}
});
}
private void toggleMenu(int duration){
if(mMenuIsOpen){
TranslateAnimation anim1 = new TranslateAnimation(0,0,0,-(mHeight-mMenuVerticalOffset));
anim1.setFillAfter(true);
anim1.setDuration(duration);
mVerticalMenu.setAnimation(anim1);
AlphaAnimation anim2 = new AlphaAnimation(0.7f, 0.0f);
anim2.setFillAfter(true);
anim2.setDuration(duration);
menu_option_01.setOnClickListener(null);
menu_option_02.setOnClickListener(null);
menu_option_03.setOnClickListener(null);
mMenuIsOpen = false;
}
else{
TranslateAnimation anim1 = new TranslateAnimation(0,0,-(mHeight-mMenuVerticalOffset),0);
anim1.setFillAfter(true);
anim1.setDuration(duration);
mVerticalMenu.setAnimation(anim1);
AlphaAnimation anim2 = new AlphaAnimation(0.0f, 0.7f);
anim2.setFillAfter(true);
anim2.setDuration(duration);
menu_option_01.setOnClickListener(mButtonClickListener);
menu_option_02.setOnClickListener(mButtonClickListener);
menu_option_03.setOnClickListener(mButtonClickListener);
mMenuIsOpen = true;
}
}
private OnClickListener mButtonClickListener = new OnClickListener()
{
public void onClick(View v)
{
toggleMenu(1000);
if(!v.isSelected()){
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
switch(v.getId()){
case R.id.menu_option_01:
// replace content_container by fragment 1
break;
case R.id.btn_02:
// replace content_container by fragment 2
break;
case R.id.btn_03:
// replace content_container by fragment 3
break;
}
}
}
};
private OnClickListener mBgClickListener = new OnClickListener()
{
public void onClick(View v)
{
toggleMenu(1000);
}
};
Main layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/content_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="44dp" />
<FrameLayout
android:id="#+id/top_bar_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false" />
</RelativeLayout>
top bar layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000" >
<LinearLayout
android:id="#+id/vertical_menu"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_marginTop="44dp"
android:background="#ffffff"
android:orientation="vertical"
android:visibility="gone" >
<!-- menu layout -->
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="#ffffff" >
<Button
android:id="#+id/btn_menu"
android:layout_width="50dp"
android:layout_height="44dp"
android:background="#drawable/menubtn" />
<ImageView
android:layout_width="130dp"
android:layout_height="44dp"
android:src="#drawable/logo"
android:layout_alignParentRight="true" />
</RelativeLayout>
</RelativeLayout>
At the end of my Toggle method, I invalidate the root view:
rootView.invalidate();
and now it works. Not quite clear why I must do that though...
I know there is already an accepted answer for this but I had a similar problem and the answer didnt help.
I had a view that I declared at the end of my layout to keep its Z index above its siblings. I had to touch the page to make the animation work.
So I set the Z index again through Java and it worked.
view.bringToFront();