Here i have one view pager activity which has one imageview and 2 overlay bars. there overlay bars i made using android xml file layout itself.
Here my requirement is like that
1) single tap on view pager's imageview first time = show top and bottom rectangle overlaybar.
2) single tap on view pager's imageview second time = hide these overlays.
These both are functions like android gallary view type.
But here when these top and bottom layout bar displays at that time i want to use only buttons click only which buttons are declare within this layout.
But I am not getting success to achieve this thing.
Problems
1) when top or bottom bar is there if i can click on next or previous button than its takes event for behind imageview single tap touch event, And my bar is getting invisible.
2) Only wants declare buttons event only
3) Avoid imageview getting clicked when i touch to overlay bar.
In short when my top and bottom image bar appears at that time no touh event takes place for imageview from top and bottom image bar. I can click on imageview but not making clickable when i click on actually next or previous or share button.
So these are the problems which i am facing, Please help me .
Source code :
activity_pager_image.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<RelativeLayout
android:id="#+id/rl_top_overlay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/slideshow_bar"
android:visibility="gone" >
<TextView
android:id="#+id/tv_top_overlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textIsSelectable="false" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/rl_bottom_overlay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#drawable/slideshow_bar"
android:visibility="visible" >
<Button
android:id="#+id/btn_left_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="35dp"
android:background="#drawable/ic_left_arrow" />
<Button
android:id="#+id/btn_below_share"
style="#style/normalText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="35dp"
android:background="#drawable/ic_share"
android:visibility="visible" />
<Button
android:id="#+id/btn_right_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginLeft="50dp"
android:layout_toRightOf="#id/btn_left_arrow"
android:background="#drawable/ic_right_arrow" />
</RelativeLayout>
</FrameLayout>
item_pager_image.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<demo.android.library.imagezoom.ImageViewTouch
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="true"
android:contentDescription="#string/descr_image"
android:scaleType="fitXY" />
</FrameLayout>
JAVA code
public class ImagePagerActivity extends BaseActivity {
private static final String STATE_POSITION = "STATE_POSITION";
private DisplayImageOptions options;
private String[] imageUrls;
private ViewPager pager;
private static int sCounter = 0;
private RelativeLayout mRlTopOverlayBar = null;
private RelativeLayout mRlBottomOverlayBar = null;
private TextView mPageNumberText = null;
private Button mLeftArrow = null;
private Button mRightArrow = null;
int mPageCounter = 0;
int mTotalImages = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_pager);
mRlTopOverlayBar = (RelativeLayout) findViewById(R.id.rl_top_overlay);
mRlBottomOverlayBar = (RelativeLayout) findViewById(R.id.rl_bottom_overlay);
mPageNumberText = (TextView) findViewById(R.id.tv_top_overlay);
mLeftArrow = (Button) findViewById(R.id.btn_left_arrow);
mRightArrow = (Button) findViewById(R.id.btn_right_arrow);
Bundle bundle = getIntent().getExtras();
String[] imageUrls = bundle
.getStringArray(Constants.GALLARY_IMAGES_IMAGE_BUNDLE_KEY);
mTotalImages = imageUrls.length;
mPageCounter = bundle.getInt(
Constants.GALLARY_IMAGE_POSITION_BUNDLE_KEY, 0);
Log.d("TAG", "Pre Poistion " + mPageCounter);
if (savedInstanceState != null) {
mPageCounter = savedInstanceState.getInt(STATE_POSITION);
}
options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.photo_default)
.showImageOnFail(R.drawable.ic_error).resetViewBeforeLoading()
.cacheOnDisc().imageScaleType(ImageScaleType.EXACTLY)
.bitmapConfig(Bitmap.Config.RGB_565)
.displayer(new FadeInBitmapDisplayer(300)).build();
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new ImagePagerAdapter(imageUrls));
pager.setCurrentItem(mPageCounter);
mLeftArrow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// int setCounter = mPageCounter - 1;
// if (setCounter >= 0) {
// }
pager.setCurrentItem(pager.getCurrentItem() - 1);
}
});
mRightArrow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
pager.setCurrentItem(pager.getCurrentItem() + 1);
/*
* int setCounter = mPageCounter + 1; if (setCounter <
* mTotalImages) { pager.setCurrentItem(mPageCounter + 1); }
*/
}
});
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(STATE_POSITION, pager.getCurrentItem());
}
private class ImagePagerAdapter extends PagerAdapter {
private String[] images;
private LayoutInflater inflater;
ImagePagerAdapter(String[] images) {
this.images = images;
inflater = getLayoutInflater();
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
#Override
public void finishUpdate(View container) {
}
#Override
public int getCount() {
return images.length;
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View imageLayout = inflater.inflate(R.layout.item_pager_image,
view, false);
Log.d("TAG", "Poistion " + position);
final ImageViewTouch imageView = (ImageViewTouch) imageLayout
.findViewById(R.id.image);
final DeactivableViewPager viewPager = new DeactivableViewPager(
ImagePagerActivity.this);
imageView.setOnScaleListener(new OnPageScaleListener() {
#Override
public void onScaleBegin() {
viewPager.deactivate();
}
#Override
public void onScaleEnd(float scale) {
if (scale > 1.0) {
viewPager.deactivate();
} else {
viewPager.activate();
}
}
});
imageView
.setSingleTapListener(new OnImageViewTouchSingleTapListener() {
#Override
public void onSingleTapConfirmed() {
Log.d("TAG", "setSingleTapListener");
sCounter++;
if (sCounter % 2 == 0) {
mRlTopOverlayBar.setVisibility(View.GONE);
mRlBottomOverlayBar.setVisibility(View.GONE);
} else {
mRlTopOverlayBar.setVisibility(View.VISIBLE);
mRlBottomOverlayBar.setVisibility(View.VISIBLE);
mRlBottomOverlayBar.setClickable(false);
mRlTopOverlayBar.setClickable(false);
}
}
});
imageLoader.displayImage(images[position], imageView, options,
new SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
// spinner.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "Input/Output error";
break;
case DECODING_ERROR:
message = "Image can't be decoded";
break;
case NETWORK_DENIED:
message = "Downloads are denied";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
Toast.makeText(ImagePagerActivity.this, message,
Toast.LENGTH_SHORT).show();
// spinner.setVisibility(View.GONE);
}
#Override
public void onLoadingComplete(String imageUri,
View view, Bitmap loadedImage) {
// spinner.setVisibility(View.GONE);
}
});
((ViewPager) view).addView(imageLayout, 0);
return imageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
#Override
public Parcelable saveState() {
return null;
}
#Override
public void startUpdate(View container) {
}
}
}
image :
thanks
A better way is to set the top and bottom frame to be clickable, with:
android:clickable="true"
Doing so will make sure that the view/frame itself will trap all clicking events, and will not pass it through the view behind it. Note this method works for all layout/view/controls, but many controls (such as buttons) already have this function on by default.
android:clickable="true" for top and bottom bar.
or give each FrameLayout an onClickListener.
just add this to each of your framelayout view containers so that absorb the click:
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
By default, some controls have clickable property as true.
But the layout doesn't. For layout, we have to make them explicitly clickable so that it will grab the events of clicks or touches and will not let it pass to background views. This is how we do it:
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
Add these lines to all your layouts, so that it will grab/absorb events and will not let it pass to background views.
#gordon1hd1 answer is correct but for those who are still confused, I am adding my layout which contains a FrameLayout as parent and a LinearLayout and twoImageViews as childs.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/scroll_parent"
android:orientation="horizontal" />
<ImageView
android:id="#+id/ivArrowLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:src="#drawable/actionbar_back"
android:layout_gravity="left|center_vertical"
android:background="#3f808080"
android:clickable="true"
/>
<ImageView
android:id="#+id/ivArrowRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="4dp"
android:src="#drawable/actionbar_back"
android:layout_gravity="right|center_vertical"
android:background="#3f808080"
android:rotation="180"
android:clickable="true"
/>
</FrameLayout>
Previously, the Linearlayout was also intercepting touch events when either of ImageViews were pressed. Adding android:clickable="true" to both ImageViews resolved the issue.
If you are also facing this type of issue, add android:clickable="true" to the view you want to trap the clicking event.
Simply, Set android:clickable="true" in xml to your foreground view.
imageView.setSingleTapListener(new OnImageViewTouchSingleTapListener() {
#Override
public void onSingleTapConfirmed() {
Log.d("TAG", "setSingleTapListener");
sCounter++;
if (sCounter % 2 == 0) {
mRlTopOverlayBar.setVisibility(View.GONE);
mRlBottomOverlayBar.setVisibility(View.GONE);
pager.requestFocus();
} else {
mRlTopOverlayBar.setVisibility(View.VISIBLE);
mRlBottomOverlayBar.setVisibility(View.VISIBLE);
mRlTopOverlayBar.requestFocus();
mRlBottomOverlayBar.requestFocus();
mRlBottomOverlayBar.setClickable(true);
mRlTopOverlayBar.setClickable(true);
}
}
});
Add android:clickable="true" to rl_bottom_overlay and rl_top_overlay. If you don´t set click events to these layouts (nor via XML neither programatically), no events will be triggered on background views.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/llSettings"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="right"
android:background="#ff106279"
android:minHeight="25px"
android:minWidth="25px"
android:onClick="click"
android:orientation="vertical"
android:visibility="visible">
<LinearLayout
android:id="#+id/llSettings1"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:background="#ff000f"
android:clickable="true"
android:minHeight="25px"
android:minWidth="25px"
android:orientation="vertical"
android:visibility="visible">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:onClick="buttonclick"
android:text="New Button" />
</LinearLayout>
</RelativeLayout>
and
public void click(View v) {
Toast.makeText(this, "((RelativeLayout)v).toString()", Toast.LENGTH_SHORT).show();
}
public void buttonclick(View v) {
Toast.makeText(this, "Button", Toast.LENGTH_SHORT).show();
}
// For removing click event, sometime click=true not work
relBottomConfirm.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
return;
}
});
Related
I have been working with Team Blox TreeView for about 3 month now with no issues, but after the update from 0.1.0 to (0.1.1 or 0.1.2), I have experienced the following strange situation. I have tried to reproduce the situation I have been experiencing using the code below:
1) TreeViewTest.class:--------------
public class TreeViewTest extends AppCompatActivity {
private static final String TAG = "TreeViewTest";
private DrawerLayout dl_treeview_out;
private ActionBarDrawerToggle drawerToggle;
private FrameLayout fl_treeview_out;
private TreeView treev_treeview_out;
private BaseTreeAdapter adapter_out;
private TreeView treev_treeview_in;
private BaseTreeAdapter adapter_in;
private TextView tv_treeview_in;
private Button b_treeview_in;
private View inView;
private TreeNode mCurrentNodeOut;
private TreeNode mCurrentNodeIn;
private List<String> items;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.treeview_out);
items = new ArrayList<String>();
for(int i = 0 ; i<=10 ; i++){
if(i == 0) {
items.add(i, "A" + "_" + "B");
}else{
items.add(i, "A" + i + "_" + "B" + i);
}
}
// Out View -------------------------------- START
dl_treeview_out = (DrawerLayout) findViewById(R.id.dl_treeview_out);
drawerToggle = new ActionBarDrawerToggle(this, dl_treeview_out , R.string.open, R.string.close) {
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu();
}
public void onDrawerClosed(View view) {
invalidateOptionsMenu();
}
};
try {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}catch (Exception e){
Log.e(TAG , " " , e);
}
treev_treeview_out = (TreeView) dl_treeview_out.findViewById(R.id.treev_treeview_out);
treev_treeview_out.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
mCurrentNodeOut = adapter_out.getNode(i);
if(mCurrentNodeOut.getData().toString().contains("A")){
fl_treeview_out.removeAllViews();
fl_treeview_out.addView(inView);
tv_treeview_in.setText("In View");
b_treeview_in.setText("~");
TreeNode inNode = new TreeNode("B");
adapter_in.setRootNode(inNode);
dl_treeview_out.openDrawer(Gravity.START , true);
}
}
});
adapter_out = new BaseTreeAdapter<ViewHolderOut>(TreeViewTest.this, R.layout.treeview_out_node) {
#NonNull
#Override
public ViewHolderOut onCreateViewHolder(View view) {
return new ViewHolderOut(view);
}
#Override
public void onBindViewHolder(ViewHolderOut viewHolder, Object data, int position) {
viewHolder.tv_out.setText(data.toString());
}
};
treev_treeview_out.setAdapter(adapter_out);
TreeNode outNode = new TreeNode("A");
adapter_out.setRootNode(outNode);
fl_treeview_out = (FrameLayout) dl_treeview_out.findViewById(R.id.fl_treeview_out);
// Out View -------------------------------- END
// In View -------------------------------- START
inView = getLayoutInflater().inflate(R.layout.treeview_in , null);
treev_treeview_in = (TreeView) inView.findViewById(R.id.treev_treeview_in);
treev_treeview_in.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
mCurrentNodeIn = adapter_in.getNode(i);
if(mCurrentNodeIn.getData().toString().contains("B")){
Toast.makeText(getApplicationContext() , "Data In: " + mCurrentNodeIn.getData().toString() , Toast.LENGTH_LONG).show();
}
}
});
adapter_in = new BaseTreeAdapter<ViewHolderIn>(TreeViewTest.this, R.layout.treeview_in_node) {
#NonNull
#Override
public ViewHolderIn onCreateViewHolder(View view) {
return new ViewHolderIn(view);
}
#Override
public void onBindViewHolder(ViewHolderIn viewHolder, Object data, int position) {
viewHolder.tv_in.setText(data.toString());
}
};
treev_treeview_in.setAdapter(adapter_in);
tv_treeview_in = (TextView) inView.findViewById(R.id.tv_treeview_in);
b_treeview_in = (Button) inView.findViewById(R.id.b_treeview_in);
b_treeview_in.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
makeSelectListDialog("Select", TreeViewTest.this, items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
try {
String[] data_split = items.get(i).split("_");
if(data_split.length == 2){
if(data_split[0].contains("A") && data_split[1].contains("B")){
mCurrentNodeOut.setData(data_split[0]);
adapter_in.getNode(0).setData(data_split[1]);
adapter_in.notifyDataChanged(adapter_in.getNode(0));
adapter_out.notifyDataChanged(mCurrentNodeOut);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).show();
}
});
// In View -------------------------------- END
}
private class ViewHolderOut {
CardView cv_out;
TextView tv_out;
ViewHolderOut(View view) {
cv_out = (CardView) view.findViewById(R.id.cv_out);
tv_out = (TextView) cv_out.findViewById(R.id.tv_out);
}
}
private class ViewHolderIn {
CardView cv_in;
TextView tv_in;
ViewHolderIn(View view) {
cv_in = (CardView) view.findViewById(R.id.cv_in);
tv_in = (TextView) cv_in.findViewById(R.id.tv_in);
}
}
public static <T> AlertDialog makeSelectListDialog(String prompt,
Context finalContext, List<T> listItems, final DialogInterface.OnClickListener onYesListener,
final DialogInterface.OnClickListener onNoListener) {
final ArrayAdapter<T> adapt =
new ArrayAdapter<T>(finalContext, android.R.layout.select_dialog_item, listItems);
AlertDialog a = new AlertDialog.Builder(finalContext)
.setTitle(prompt)
.setAdapter(adapt, onYesListener)
.setNegativeButton("Cancel", onNoListener)
.create();
return a;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item)) {
return true;
}else {
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
}
2) treeview_out.xml:--------------------
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/dl_treeview_out"
android:layout_width="match_parent"
android:background="#android:color/white"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff">
<de.blox.treeview.TreeView
android:id="#+id/treev_treeview_out"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:useMaxSize="true"
app:lineColor="#android:color/holo_blue_dark"/>
</android.support.design.widget.CoordinatorLayout>
<FrameLayout
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:id="#+id/fl_treeview_out">
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
3) treeview_out_node.xml:---------
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cv_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
card_view:cardElevation="18dp"
card_view:contentPadding="11dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tv_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textColor="?attr/colorAccent"
android:textStyle="bold"/>
</LinearLayout>
</android.support.v7.widget.CardView>
4) treeview_in.xml:----------
<?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"
android:weightSum="100"
android:id="#+id/ll_treeview_in"
android:layout_gravity="start">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_weight="10"
android:background="#color/colorPrimaryDark"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:textStyle="bold"
android:gravity="center"
android:layout_toStartOf="#id/b_treeview_in"
android:layout_alignParentStart="true"
android:layout_gravity="center"
android:background="?attr/colorPrimary"
android:textColor="#android:color/white"
android:id="#+id/tv_treeview_in"/>
<Button
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_alignParentEnd="true"
android:textAllCaps="false"
android:layout_marginEnd="2.5dp"
android:layout_marginStart="2.5dp"
android:layout_marginTop="2.5dp"
android:layout_marginBottom="2.5dp"
android:textColor="#android:color/white"
android:background="#color/colorPrimary"
android:layout_gravity="center"
android:gravity="center"
android:id="#+id/b_treeview_in"/>
</RelativeLayout>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_weight="90"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#fff">
<de.blox.treeview.TreeView
android:id="#+id/treev_treeview_in"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:levelSeparation="20dp"
app:lineColor="#android:color/holo_green_light"/>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
5) treeview_in_node.xml:-------------------
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cv_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
card_view:cardElevation="18dp"
card_view:contentPadding="11dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tv_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textColor="?attr/colorAccent"
android:textStyle="bold"/>
</LinearLayout>
</android.support.v7.widget.CardView>
6) In the code above, I have created two TreeViews (one directly inside activity and another one inside a drawer in this activity) with one block each. First TreeView block contains data starting with A (A , A1 , A2 , ...), where as Second TreeView block contains data starting with B (B , B1 , B2 , ...). The idea here is that I'm trying to change the data of first TreeView block and second TreeView block at the same time by clicking a button from inside the drawer (b_treeview_in) and selecting data from a list which opens. The above code works properly (data of both TreeView blocks is getting updated) in version 0.1.0 of this library, but not working properly (First TreeView block data is getting updated, but the second TreeView block data is not) after the update to version (0.1.1 or 0.1.2). Note: In both cases if I check the data, I find that it changed to what was selected from the list, but visually in case of the second TreeView block it didn't change to what was selected.
7) If this problem is caused by notifyDataChanged() or adapter.getNode(), then why is it working for the first TreeView block?
8)
In case of version 0.1.0
In case of version 0.1.1 or 0.1.2
Developer of TreeView here!
Unfortunatly this issues was causes by the library. I uploaded a new Version, which should fix it. Please try it out.
I am having a weird issue in my app. In one of my app activity I am inflating three fragments in it with tabs. Everything works fine.
In the fragment in which I am having problem, I have listview which is inflated using adapter and data fro web service. This also works well. Now the problem is this the row which is inflated in adapter, has a hidden view which has visibility=gone in xml. On tap of imageview from that row I make that layout visible through java code. The problem is layout doesn't become visible on tap. I have even set breakpoint on the onClickListener of imageview and it does execute the line which changes the visibility from gone to visible. I am unable to understand what is causing this issue as I am using the same row xml with same data in other screen and there it is working perfectly.
UPDATE
I got to know what's causing this issue but don't know how to solve this. In my activity I am having three fragments. The view that I provided for fragment(in which fragment will be inflated) is causing main problem. I have set height width to match parent but it is not taking match parent height. If the fragment just includes normal views like textview, imageview then also fragment is shown properly.But the problem is if fragment consists of listview, then it only takes height of the custom row that is supplied to the listview. I am able to scroll complete listview in that space.
I don't understand what is causing this behaviour.
My Updated code.
Main layout xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<include layout="#layout/header_1" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#000"
android:weightSum="3"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:weightSum="1"
android:orientation="horizontal"
android:id="#+id/lin_birds">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="#string/aves"
android:textColor="#ffffff"
android:gravity="center"
android:layout_gravity="center"
android:layout_weight="0.99"
android:id="#+id/fragment_aves"/>
<View
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="0.01"
android:background="#ffffff"
android:layout_marginTop="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:weightSum="1"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="#string/routes"
android:textColor="#ffffff"
android:gravity="center"
android:layout_gravity="center"
android:layout_weight="0.99"
android:id="#+id/fragment_routes"/>
<View
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="0.01"
android:background="#ffffff"
android:layout_marginTop="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/information"
android:textColor="#ffffff"
android:gravity="center"
android:layout_gravity="center"
android:id="#+id/fragment_information"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frame_details" />
</LinearLayout>
</LinearLayout>
Main activity java code
public class ActivityRoutesDetails extends AppCompatActivity {
RelativeLayout rel_back;
TextView tv_title,tv_information,tv_routes,fragment_aves;
RoutesDataBean routesDataBean;
LinearLayout frame;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.routes_detail);
tv_title= (TextView)findViewById(R.id.tv_title);
tv_information= (TextView) findViewById(R.id.fragment_information);
tv_routes= (TextView) findViewById(R.id.fragment_routes);
fragment_aves= (TextView) findViewById(R.id.fragment_aves);
// frame= (LinearLayout) findViewById(R.id.frame_details);
routesDataBean= (RoutesDataBean)getIntent().getSerializableExtra("data");
tv_title.setText(routesDataBean.getDescrip1());
Fragment fragment=new FragmentRouteInside();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_details, fragment);
fragmentTransaction.commit();
fragment_aves.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragmentBirds=new FragmentRouteBirds();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_details, fragmentBirds);
fragmentTransaction.commit();
}
});
tv_information.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragmentRouteInformation = new FragmentRouteInformation();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_details, fragmentRouteInformation);
fragmentTransaction.commit();
}
});
tv_routes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragment=new FragmentRouteInside();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_details, fragment);
fragmentTransaction.commit();
}
});
rel_back= (RelativeLayout) findViewById(R.id.rel_back);
rel_back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
}
fragment bird xml
<?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">
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lv_bird"/>
</LinearLayout>
Fragment java code
public class FragmentRouteBirds extends Fragment {
AppSharedPreferences appSharedPreferences;
String REGISTER_URL="";
ListView lv_birds;
private ArrayList<BirdsDataBean> birdsUrlList;
boolean flag=false;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragments_birds, null);
appSharedPreferences=AppSharedPreferences.getsharedprefInstance(getActivity());
REGISTER_URL = "http://192.241.162.63/appvist/v1/routebird/"+appSharedPreferences.getRouteId();
birdsUrlList = new ArrayList<>();
lv_birds = (ListView) root.findViewById(R.id.lv_bird);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) lv_birds.getLayoutParams();
lp.height = LinearLayout.LayoutParams.MATCH_PARENT;
lv_birds.setLayoutParams(lp);
hitBirdsService();
return root;
}
private void hitBirdsService() {
class RegisterUser extends AsyncTask<String, Void, String> {
private ProgressDialog mDialog;
RequestClass ruc = new RequestClass();
String response = "";
#Override
protected void onPreExecute() {
super.onPreExecute();
mDialog = new ProgressDialog(getActivity());
mDialog.setMessage("Please Wait ...");
mDialog.setCancelable(false);
mDialog.show();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
mDialog.dismiss();
parseBirdResponse(response);
//Toast.makeText(getActivity(), s, Toast.LENGTH_LONG).show();
}
#Override
protected String doInBackground(String[] params) {
response = RequestClass.GET(REGISTER_URL);
return response;
}
}
RegisterUser ru = new RegisterUser();
ru.execute();
}
public void parseBirdResponse(String response) {
//String descrip, String observaciones, String descrip_larga, String url_video, String url
try {
JSONObject jsonObject = new JSONObject(response);
Boolean error = jsonObject.getBoolean("error");
if (!error) {
JSONArray jsonArray = jsonObject.getJSONArray("birds");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonBirds = jsonArray.getJSONObject(i);
int idave=jsonBirds.getInt("idave");
String descrip = jsonBirds.getString("descrip");
String observaciones = jsonBirds.getString("observaciones");
String descrip_larga = jsonBirds.getString("descrip_larga");
String url_video = jsonBirds.getString("url_video");
String url = jsonBirds.getString("url");
String nombre_cientifico = jsonBirds.getString("nombre_cientifico");
int flag=jsonBirds.getInt("flag");
birdsUrlList.add(new BirdsDataBean(flag,idave,descrip, observaciones, descrip_larga, url_video, url, nombre_cientifico));
}
ScheduleTaskAdapter scheduleTaskAdapter = new ScheduleTaskAdapter(getActivity(), birdsUrlList);
lv_birds.setAdapter(scheduleTaskAdapter);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) lv_birds.getLayoutParams();
lp.height = 800;
lv_birds.setLayoutParams(lp);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public class ScheduleTaskAdapter extends BaseAdapter {
Context context;
LayoutInflater layoutInflater;
// List<InterestAndLanguageBean> interestAndLanguageBeans=new ArrayList<>();
List<BirdsDataBean> imageList = new ArrayList<>();
public ScheduleTaskAdapter(Context context, List<BirdsDataBean> imagesList) {
this.context = context;
this.imageList = imagesList;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return imageList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = layoutInflater.inflate(R.layout.routes_bird_row, parent, false);
holder.iv_birds = (ImageView) convertView.findViewById(R.id.iv_route_bird);
holder.frameLayout = (FrameLayout) convertView.findViewById(R.id.frame_route_bird);
holder.linearLayout = (LinearLayout) convertView.findViewById(R.id.route_bird_detail_view);
holder.imageView = (ImageView) convertView.findViewById(R.id.iv_hide);
holder.iv_video = (ImageView) convertView.findViewById(R.id.iv_seen);
holder.iv_sound = (ImageView) convertView.findViewById(R.id.iv_video);
holder.tv_short_descript = (TextView) convertView.findViewById(R.id.tv_bird_name);
holder.tv_category = (TextView) convertView.findViewById(R.id.tv_scientific_name);
holder.tv_long_description = (TextView) convertView.findViewById(R.id.tv_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Uri myUri = Uri.parse(birdsUrlList.get(position).getUrl());
Glide.with(getActivity()).load(myUri).placeholder(R.drawable.birds).into(holder.iv_birds);
holder.tv_short_descript.setText(birdsUrlList.get(position).getDescrip());
holder.tv_long_description.setText(birdsUrlList.get(position).getDescrip_larga());
holder.tv_category.setText(birdsUrlList.get(position).getNombre_cientifico());
final ViewHolder finalHolder = holder;
holder.frameLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finalHolder.linearLayout.setVisibility(View.VISIBLE);
finalHolder.iv_sound.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(birdsUrlList.get(position).getUrl_video())));
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
});
finalHolder.iv_video.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//hitBirdSeenService(birdsUrlList.get(position).getIdave());
// finalHolder.iv_video.setImageResource(R.drawable.eye_selected);
}
});
}
});
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finalHolder.linearLayout.setVisibility(View.GONE);
}
});
//Picasso.with(context).load(myUri).placeholder(R.drawable.image).into(holder.pic);
//malevich.load(helperTaskBeanList.get(position).getImage()).into(holder.pic);
return convertView;
}
}
static class ViewHolder {
ImageView iv_birds,imageView,iv_video,iv_sound;
FrameLayout frameLayout;
LinearLayout linearLayout;
TextView tv_short_descript,tv_category,tv_long_description;
}
}
And row layout for adapter
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="#+id/frame_route_bird"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:id="#+id/iv_route_bird"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="bottom"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="#string/name"
android:textSize="24sp"
android:textStyle="bold"
android:id="#+id/tv_bird_name"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textColor="#ffffff"
android:text="#string/bird_sub_category"
android:id="#+id/tv_scientific_name"/>
</LinearLayout>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone"
android:background="#ffffff"
android:id="#+id/route_bird_detail_view"
android:paddingBottom="120dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/bird_hidden_text"
android:textSize="20sp"
android:padding="20dp"
android:id="#+id/tv_description"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/eye110"
android:id="#+id/iv_seen"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/right"
android:layout_marginTop="25dp"
android:layout_marginLeft="15dp"
android:id="#+id/iv_arrow"/>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/ear"
android:layout_marginLeft="15dp"
android:id="#+id/iv_video"/>
</LinearLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#D6D6D6"
android:layout_marginTop="20dp"
android:src="#drawable/up"
android:layout_gravity="center"
android:id="#+id/iv_hide"/>
</LinearLayout>
</LinearLayout>
Here are the screenshots of the problem
Comparing both images you can see that the hidden view appears in the space of the single row item and is scroll able completely in that space.
Better upshot were targeted at plus for android developers (Cristophe Beils):
"Your ListView must have its height set to match_parent or a fixed size, not wrap_content.
If you need to add another view fixed at the bottom of the ListView as a footer, you need to put both the ListView and the footer View in a vertical LinearLayout and set layout_height to 0dp and layout_weight to 1 on the ListView so that it takes the remaining vertical space."
Try fillViewPort=true on the list view.. But not sure what why yoi have a scroll view inside a list view.. Could be the issue too.
Try setting match_parent as the height of the listview
I suspect this will force the list view to have a defined height and fix your problem.
In my app I'm using a Toolbar. Now in inside my Toolbar I have two ImageViews. When the user clicks on any of the ImageViews I open different Fragment or Activity but in my case I'm not able to click on any of the ImageViews.
*.xml
<?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:background="#drawable/background"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_home"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#drawable/background"
android:elevation="2dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_home_about_us"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:src="#drawable/about" />
<ImageView
android:id="#+id/iv_home_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/iv_home_about_us"
android:layout_marginRight="10dp"
android:src="#drawable/search" />
</RelativeLayout>
</android.support.v7.widget.Toolbar>
<TextView
style="#style/text_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="05dp"
android:gravity="center"
android:text="Trending around me" />
<com.techmorphosis.wheretoday.SlidingTabs.SlidingTabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="50dp"
android:padding="10dp" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"></android.support.v4.view.ViewPager>
</LinearLayout>
Complete Code
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.home_screen, container, false);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
if (!bundle.isEmpty()) {
position = bundle.getInt(FROM_WHERE_ERROR_OCCURED);
}
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
latitude = SettingPreffrences.getLatitude(contextFrag);
longitude = SettingPreffrences.getLongitude(contextFrag);
if (latitude.equals("") && longitude.equals("")) {
commonFunctions.isLocationAvailable();
commonFunctions.replaceFragment(getActivity(), new ErrorFrag().newInstance(100, 0), false);
} else {
initialize();
}
}
private void initialize() {
toolbar = (Toolbar) view.findViewById(R.id.toolbar_home);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
// actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
// actionBar.setDisplayShowTitleEnabled(false);
ivAboutUs = (ImageView) toolbar.findViewById(R.id.iv_home_about_us);
ivSearch = (ImageView) toolbar.findViewById(R.id.iv_home_search);
pager = (ViewPager) view.findViewById(R.id.pager);
pager.setAdapter(new MyPagerAdapter(getActivity().getSupportFragmentManager()));
tabLayout = (SlidingTabLayout) view.findViewById(R.id.tabs);
tabLayout.setDistributeEvenly(true);
tabLayout.setSelectedIndicatorColors(Color.TRANSPARENT);
tabLayout.setViewPager(pager);
if (position == 0) {
pager.setCurrentItem(0, true);
} else if (position == 1) {
pager.setCurrentItem(1, true);
} else if (position == 2) {
pager.setCurrentItem(2, true);
}
ivAboutUs.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(contextFrag, "Yess", Toast.LENGTH_SHORT).show();
}
});
ivSearch.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_home_about_us:
commonFunctions.replaceFragment(getActivity(), new AboutUsFrag(), false);
break;
case R.id.iv_home_search:
Intent intent = new Intent(contextFrag, SearchScreen.class);
contextFrag.startActivity(intent);
break;
}
}
}
class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new TodayFrag();
}
if (position == 1) {
fragment = new TommorowFrag();
}
if (position == 2) {
fragment = new LaterFrag();
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
}
You can't access the UI element in onCreateView method - EVER
Use onActivityCreated method , that tell the fragment the activity is fully created and ready to interact.
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
ImageView ivAboutUs = (ImageView) view.findViewById(R.id.iv_home_about_us);
ivAboutUs .setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
This might be an issue where the touch events never reach the ImageViews because they were absorbed by something else. I ran into something similar where I was trying to put an onClickListener on an Imageview embedded in a list item. No matter how much I clicked on the imageView, something else was eating up the touch events(Most likely the View that makes up the ListView Item. I fixed the problem by changing the ImageView to an ImageButton and setting its background to null (So that the imageButton would look like an imageView and not an image button.) Once I did that, clicking the images worked for me. Try changing your ImageViews to look like this:
<ImageButton
android:id="#+id/iv_home_about_us"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="#null"
android:src="#drawable/about" />
<ImageView
android:id="#+id/iv_home_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/iv_home_about_us"
android:layout_marginRight="10dp"
android:background="#null"
android:src="#drawable/search" />
I hope this helps. Good luck.
I have implemented both a ViewHolder and a convertView in my listView.
My listView is populated by a custom adapter, with a list of bookings.
When I click on an item, an invisible layout slides in from right to left, to display buttons.
I can dismiss this overlaying layout by clicking on a dismiss button so that it gets hidden again.
On this overlaying layout, I have a delete Button, which enables me to delete the item.
So far so good.
When I erase an item the item disappears as expected, the adapter is then reloaded.
The item below takes the position of the deleted item, but remains invisible.
I know it is here, because I can still click on the item to trigger the overlaying View.
So the ovelaying view is visible but not the item. I have no idea why this is happening.
I suspect the ViewHolder to be responsible of this behaviour, but I can't find a solution.
Thank you for your help.
See video here : http://youtu.be/KBGEvbUq-V0
My Bookings Class :
public class BookingsListFragment extends Fragment {
private final String SHOP_NAME_KEY = "ShopName";
private final String SHOP_ADDRESS_KEY = "ShopAddress";
public static int mSelectedItem = -1;
private static ListView mBookingsListView;
private static BookingsListViewAdapter mBookingsListViewAdapter;
private static ArrayList<Booking> mBookings;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(getActivity()));
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bookings_list_fragment, container, false);
configureListView(view);
return view;
}
#Override
public void onResume() {
super.onResume();
mSelectedItem = -1;
}
private void configureListView(View view) {
mBookings = BookingsHandler.getBookings();
mBookingsListView = (ListView) view.findViewById(R.id.bookingsListView);
mBookingsListViewAdapter = new BookingsListViewAdapter();
mBookingsListView.setAdapter(mBookingsListViewAdapter);
mBookingsListView.setTextFilterEnabled(true);
}
public static void updateBookingsListView(ArrayList<Booking> mBookingsList){
mBookings = mBookingsList;
mBookingsListViewAdapter.notifyDataSetChanged();
}
static class ViewHolder {
LinearLayout bookingItemLL;
RelativeLayout optionsOverlay;
TextView productName;
TextView price;
TextView shopName;
TextView endDate;
ImageView productImage;
LinearLayout placeholderLL;
Button cancelBooking;
Button displayDirections;
Button callShop;
ImageView discardOverlay;
}
private class BookingsListViewAdapter extends BaseAdapter {
private static final int TYPE_ITEM = 0;
private static final int TYPE_PLACEHOLDER = 1;
#Override
public int getCount() {
if (mBookings != null)
return mBookings.size();
else
return 1;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
// Define a way to determine which layout to use
if (mBookings != null && mBookings.size() > 0)
return TYPE_ITEM;
else
return TYPE_PLACEHOLDER;
}
#Override
public int getViewTypeCount() {
return 2; // Number of different layouts
}
#Override
public View getView(final int position, View convertView, ViewGroup viewGroup) {
int type = getItemViewType(position);
final ViewHolder holder;
if(convertView == null) {
holder = new ViewHolder();
switch (type){
case TYPE_ITEM :
convertView = LayoutInflater.from(getActivity()).inflate(R.layout.bookings_item, null);
holder.bookingItemLL = (LinearLayout) convertView.findViewById(R.id.bookingItemLL);
holder.optionsOverlay = (RelativeLayout) convertView.findViewById(R.id.bookingOptionsOverlay);
holder.productName = (TextView) convertView.findViewById(R.id.bookingProductName);
holder.price = (TextView) convertView.findViewById(R.id.bookedProductPrice);
holder.shopName = (TextView) convertView.findViewById(R.id.bookingShopName);
holder.endDate = (TextView) convertView.findViewById(R.id.bookingEndDate);
holder.productImage = (ImageView) convertView.findViewById(R.id.bookedProductImage);
holder.displayDirections = (Button) convertView.findViewById(R.id.routeShop);
holder.cancelBooking = (Button) convertView.findViewById(R.id.cancelBooking);
holder.callShop = (Button) convertView.findViewById(R.id.callShop);
holder.discardOverlay = (ImageView) convertView.findViewById(R.id.discardOverlay);
break;
case TYPE_PLACEHOLDER :
convertView = LayoutInflater.from(getActivity()).inflate(R.layout.booking_placeholder, null);
holder.placeholderLL = (LinearLayout) convertView.findViewById(R.id.placeHolderLL);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
if(type == 0) {
if(position == mSelectedItem){
holder.optionsOverlay.setVisibility(View.VISIBLE);
configureOverlayButtons(holder);
}
holder.bookingItemLL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mSelectedItem != position && mSelectedItem != -1){
View item = mBookingsListView.getChildAt(mSelectedItem - mBookingsListView.getFirstVisiblePosition());
if(item != null){
RelativeLayout overlayOptions = (RelativeLayout) item.findViewById(R.id.bookingOptionsOverlay);
overlayOptions.setVisibility(View.GONE);
}
}
Animation slideInAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.booking_options_overlay_animation);
holder.optionsOverlay.startAnimation(slideInAnimation);
holder.optionsOverlay.setVisibility(View.VISIBLE);
mSelectedItem = position;
configureOverlayButtons(holder);
}
});
final Booking booking = mBookings.get(position);
holder.productName.setText(booking.getName().toUpperCase());
holder.price.setText("Prix lors de la réservation : " + String.format("%.2f", Float.valueOf(booking.getPrice())) + " €");
holder.shopName.setText(booking.getShopName());
holder.endDate.setText(booking.getEndDate());
holder.productImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.product_placeholder)
.showImageOnFail(R.drawable.product_no_image_placeholder)
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.displayImage(BeeWylApiClient.getImageUrl(booking.getImageURL()),holder.productImage, options);
}
if(type == 1){
holder.placeholderLL.setLayoutParams(BeeWylHelper.getPlaceHolderSizeForFreeScreenSpace(getActivity(),0));
}
return convertView;
}
private void configureOverlayButtons(final ViewHolder holder){
holder.cancelBooking.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder ab = new AlertDialog.Builder(getActivity());
ab.setMessage("Annuler la réservation ?").setPositiveButton("Oui", dialogClickListener)
.setNegativeButton("Non", dialogClickListener).show();
}
});
holder.displayDirections.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
launchMapActivity();
}
});
holder.callShop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
launchDialer();
}
});
holder.discardOverlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Animation hideOverlayAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.booking_overlay_dismiss);
holder.optionsOverlay.startAnimation(hideOverlayAnimation);
holder.optionsOverlay.setVisibility(View.GONE);
holder.optionsOverlay.clearAnimation();
}
});
}
private void sendCancelBookingToAPI(String id_booking) throws JsonProcessingException {
BeeWylApiClient.cancelBooking(id_booking, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int i, Header[] headers, byte[] bytes) {
try {
Log.v("xdebug CANCEL", new String(bytes, "UTF_8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
Log.v("xdebug CANCEL ERROR", String.valueOf(throwable));
}
});
}
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
Animation hideOverlayAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.booking_overlay_dismiss);
mBookingsListView.getChildAt(mSelectedItem-mBookingsListView.getFirstVisiblePosition()).startAnimation(hideOverlayAnimation);
new Handler().postDelayed(new Runnable() {
public void run() {
try {
sendCancelBookingToAPI(mBookings.get(mSelectedItem).getId());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
mBookings.remove(mSelectedItem);
mSelectedItem = -1;
updateBookingsListView(mBookings);
}
}, hideOverlayAnimation.getDuration());
break;
case DialogInterface.BUTTON_NEGATIVE:
dialog.cancel();
break;
}
}
};
}
}
And the item inflated :
<?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="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
>
<LinearLayout
android:id="#+id/bookingItemLL"
android:layout_width="match_parent"
android:layout_height="151dp"
android:orientation="horizontal"
android:weightSum="100"
android:background="#drawable/product_item_rectangle"
>
<ImageView
android:id="#+id/bookedProductImage"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#android:color/white"
android:src="#drawable/nivea"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_vertical"
>
<TextView
android:id="#+id/bookingProductName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="BRUME NIVEA"
android:textColor="#color/ProductsBlue"
android:textSize="16dp"
android:textStyle="bold"
/>
<TextView
android:id="#+id/bookedProductPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Prix lors de la réservation : 24,90€"
android:textSize="12dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:textColor="#color/ProductsBlue" android:layout_gravity="left"
/>
<TextView
android:id="#+id/bookingShopName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:text="Magasin"
android:textSize="12dp"
android:textColor="#color/ProductsBlue"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:text="Réservé jusqu'au"
android:textSize="12dp"
android:textColor="#color/ProductsBlue" />
<TextView
android:id="#+id/bookingEndDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="-"
android:textSize="12dp"
android:textColor="#color/ProductsBlue" />
</LinearLayout>
</LinearLayout>
<RelativeLayout android:id="#+id/bookingOptionsOverlay"
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="#EEFFFFFF"
android:visibility="gone">
<ImageView
android:id="#+id/discardOverlay"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="#drawable/ic_discard_booking_overlay"
android:padding="5dp"
/>
<Button android:id="#+id/callShop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="APPELER"
android:layout_weight="1"
android:background="#00000000"
android:drawableTop="#drawable/booking_call"
android:textColor="#color/ProductsBlue"
android:textSize="14dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:drawablePadding="20dp"
android:layout_marginLeft="20dp"
/>
<Button android:id="#+id/cancelBooking"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ANNULER"
android:layout_weight="1"
android:background="#00000000"
android:drawableTop="#drawable/booking_cancel"
android:textColor="#color/ProductsBlue"
android:textSize="14dp"
android:layout_centerInParent="true"
android:drawablePadding="20dp"
/>
<Button android:id="#+id/routeShop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ITINERAIRE"
android:layout_weight="1"
android:background="#00000000"
android:drawableTop="#drawable/booking_route"
android:textColor="#color/ProductsBlue"
android:textSize="14dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:drawablePadding="20dp"
android:layout_marginRight="20dp"
/>
</RelativeLayout>
</RelativeLayout>
Your problem comes from re-using the convertView.
When the previous item got a click the OnClickListener fired and in there the visibility for the item was set to GONE. Later on this same view got recycled and passed to getView() as the convertView. Because you are re-using it without resetting any changes that were made you are now working with a View for a new item that is not in a known state. You should make sure you undo any changes before using a convertView.
The quick fix is to not re-use the convertView that is passed into getView(). So, in your code where you check if you can re-use the convertView:
if(convertView == null)
Sabotage that check just to see if things start working:
if(true)
If that does the trick you will probably want to fix it properly.
In the else clause of the above check, you are getting the item holder from the tag. Also undo any changes that your OnClickListeners could have made. You want to start with a View for a new item in a known state. You should initialize it explicitly. For example:
if(convertView == null) {
// ... snipped all the initialization ...
} else {
holder = (ViewHolder)convertView.getTag();
convertView.setVisibility(View.VISIBLE);
}
Update
I have never used a 'heterogenous' adapter so I can't really answer why "the convertView is reusing the overlay View instead of my item's root View." The Android developer documentation for Adapter.getView() says about the convertView argument:
The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).
The emphasized bit says that you cannot depend on the system to pass you a convertView of the right type, while the last sentence says the opposite (as I read it).
Basically, I don't know why it's not working. I guess in the test where you check if you must inflate a new view yourself
if(convertView == null)
you should also check if it is the right kind of view:
if(convertView == null || getItemViewTypeFromView(convertView) != type)
Where getItemViewTypeFromView() is something like this:
private int getItemViewTypeFromView(View view) {
switch (view.getId()) {
case R.id.item_layout_root:
return TYPE_ITEM;
case R.id.placeholder_layout_root:
return TYPE_PLACEHOLDER;
default:
throw new UnsupportedOperationException();
}
}
In the item and placeholder layouts, give the root elements an id so you distinguish between them. So something like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item_layout_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp" >
... snipped the elements that make up the body of the layout ...
</RelativeLayout>
I haven't tried the above, so I hope it works for you.
Good luck!
I have a class that extends a Fragment. I want when press a button from An Activity to opens this Fragment with its layout in dialog in addition to that the fragment opens normally in its place. Is this possible?
This is my Fragment (TipsFragment.java)
public class TipsFragment extends Fragment{
ListView list;
TipsAdapter tipsAdapter;
AlertDialog PageDialog;
DAO db;
Cursor c;
ArrayList<HashMap<String, String>> tipsList;
HashMap<String, String> map;
ArrayList<HashMap<String, String>> pages;
Integer tipType;
ImageButton page;
ImageButton add;
ImageButton search;
EditText inputAdd;
EditText inputSearch;
ImageView addImage;
RelativeLayout layoutAdd;
RelativeLayout layoutSearch;
int itemSelected;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
db = new DAO(activity);
db.open();
}
public TipsFragment(){}
public TipsFragment(int tipType, int itemSelected ){
this.tipType = tipType;
this.itemSelected = itemSelected;
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
final Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tips_fragement, container, false);
System.out.println("tipType: "+tipType);
System.out.println("itemSelected: "+itemSelected);
page = (ImageButton) rootView.findViewById(R.id.pager);
add = (ImageButton) rootView.findViewById(R.id.add);
search = (ImageButton) rootView.findViewById(R.id.search);
inputSearch = (EditText) rootView.findViewById(R.id.inputSearch);
inputAdd = (EditText) rootView.findViewById(R.id.inputAdd);
addImage = (ImageView) rootView.findViewById(R.id.imageAdd);
layoutAdd = (RelativeLayout) rootView.findViewById(R.id.layoutAdd);
layoutSearch = (RelativeLayout) rootView.findViewById(R.id.layoutSearch);
if (tipType != 0) {
switch (tipType) {
case 1:
System.out.println("All tips");
if (getActivity().getIntent().getStringExtra("startFrom") == null) {
c = db.getTips("0");
} else {
c = db.getTips(getActivity().getIntent().getStringExtra("startFrom"));
}
break;
case 2:
System.out.println("favorite tips");
c = db.getFavoriteTips();
page.setVisibility(View.GONE);
System.out.println("in favorite, count_records: "+c.getCount());
break;
}
}
System.out.println("count_records: "+c.getCount());
if (c.getCount() != 0) {
if (getActivity().getIntent().getStringExtra("startLabel") != null) {
page = (ImageButton) rootView.findViewById(R.id.pager);
}
tipsList = new ArrayList<HashMap<String, String>>();
list = (ListView) rootView.findViewById(R.id.tipList);
do {
map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(DAO.TIP_ID, c.getString(c.getColumnIndex(c.getColumnName(0))));
map.put(DAO.TIP_CONTENT, c.getString(c.getColumnIndex(c.getColumnName(1))));
// adding HashList to ArrayList
tipsList.add(map);
} while (c.moveToNext());
// Getting adapter by passing xml data ArrayList
tipsAdapter = new TipsAdapter(getActivity(), tipsList);
list.setAdapter(tipsAdapter);
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
map = tipsList.get(position);
System.out.println("in list select item, tipType: "+tipType);
if (!MainActivity.tSlidingLayer.isOpened()) {
MainActivity.tSlidingLayer.openLayer(true);
}
}
});
page.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Strings to Show In Dialog with Radio Buttons
}
});
add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}
});
search.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}
});
inputSearch.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
}
addImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), "addImage pressed", Toast.LENGTH_LONG).show();
}
});
return rootView;
}
}
and this is layout tips_fragement.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/titleBar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/add"
android:layout_width="45dp"
android:layout_height="35dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:scaleType="fitXY"
android:src="#drawable/add" />
<ImageButton
android:id="#+id/search"
android:layout_width="45dp"
android:layout_height="35dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:scaleType="fitXY"
android:src="#drawable/search" />
<ImageButton
android:id="#+id/pager"
android:layout_width="45dp"
android:layout_height="35dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:scaleType="fitXY"
android:src="#drawable/pager" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="5dip"
android:background="#drawable/shadow" >
</View>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layoutAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" >
<EditText
android:id="#+id/inputAdd"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Add" />
<ImageView
android:id="#+id/imageAdd"
android:padding="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/inputAdd"
android:layout_alignBottom="#+id/inputAdd"
android:layout_alignRight="#+id/inputAdd"
android:src="#android:drawable/ic_menu_add" />
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/layoutSearch"
android:visibility="gone" >
<EditText
android:id="#+id/inputSearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Search"/>
<ImageView
android:id="#+id/imageSearch"
android:padding="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/inputSearch"
android:layout_alignBottom="#+id/inputSearch"
android:layout_alignRight="#+id/inputSearch"
android:src="#android:drawable/ic_menu_search" />
</RelativeLayout>
<ListView
android:id="#+id/tipList"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/buttons"
android:divider="#351802"
android:dividerHeight="2dp"
android:listSelector="#drawable/list_selector" />
</LinearLayout>
Since Android supports nesting Fragments (available in the support library) you could show your TipsFragment as a content of another DialogFragment. Avoid this solution whenever possible.
A better solution would be to make TipsFragment extend DialogFragment and that way you can either show the Fragment inline or in a dialog.
1 - Make TipsFragment extends DialogFragment
public class TipsFragment extends DialogFragment {...}
2 - On button click use FragmentTransaction.add or FragmentTransaction.replace to show the DialogFragment inline or include it in your layout and change its visibility.
3 - Show the TipsFragment as a dialog
TipsFragment fr = new TipsFragment();
fr.show(getSupportFragmentManager(), "dialog_fragment_tag");
Guide: Performing Fragment Transactions. More samples are available in the ApiDemos application from the SDK samples