Weird OnItemClick Behavior (GridView in a Fragment) - java

I'm trying to 1) reveal a view and 2) modify another view in response to a user click on a view. The clickable view is populated by an adapter and set to a GridView. In my code, mTextView is a reference to another view in rootView. There are no NullPointer errors.
The strange problems are
In my code, for whatever method I call with LINE 3's mTextView, let it be setVisibility() or whatnot, LINE3 will draw (Shows changed text HELLO WORLD in at the other view), but LINE 1 just won't draw. The strange behavior is, with LINE 3, when I click the item the second time, LINE 1 works.
When I comment LINE 3 out, LINE 1 works on the first click. So, LINE 1's view is obviously not NULL (or could it?)
Yet another strange behavior is, LINE 2 always work as expected, the background color changed the first click, with or without LINE 3.
Each LINE1,LINE2 or LINE3 work perfectly on its own, in onItemClick.
What baffles me is why does LINE2 work but not LINE1, what are the possible dependencies between LINE3, LINE2, LINE1. Here is the code.
// Setup OnItemClickListener to respond to user click
mCardsGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// store the selected favor item as an instance, if it is not set already
mSelectedGameCardItem = (GameCardItem) parent.getItemAtPosition(position);
// Make the content visible (LINE 1)
view.findViewById(R.id.game_card_item_title).setVisibility(View.VISIBLE);
// Change the background color (LINE 2)
view.findViewById(R.id.game_card_item).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorAccent));
// change tag line message at another view, rootView(LINE 3)
mTextView.setText(getResources().getString(R.string.favors_game_post_game_description, "HELLO WORLD"));
}
}
});
The XML of the item_card layout, this layout is used by the adapter to inflate the item in the grid.
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:id="#+id/game_card_item"
android:padding="8dp"
android:background="#color/colorLightPrimary"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="16dp"
app:srcCompat="#drawable/ic_mysterious_box_36dp" />
<TextView
android:id="#+id/game_card_item_title"
android:textColor="#color/colorPrimaryText"
android:textAlignment="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/TextAppearance.AppCompat.Title"
android:text="#string/favors_default_1" />
</LinearLayout>
</android.support.v7.widget.CardView>

Related

Picasso centerCrop and fit get different results

I want to insert an image to an ImageView, which gets used as a background. This background is in a RecyclerView. When it gets loaded the first time, it looks like this:
But when I scroll to another item and scroll back, it looks like this (it should always look like this):
Here i add the image:
public void onBindViewHolder(StoryViewHolder holder, int position) {
holder.cardView.setMinimumHeight(height/3);
holder.layout.setMinimumHeight((int) ((float) width / 4));
//set image
Picasso.with(activity).load(MainPostAdapter.URL + 140 + ".png").
transform(new BlurTransform(holder.background.getContext())).fit().centerCrop().into(holder.background);
holder.background.setAlpha(0.25f);
}
And this is the image itself:
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/story_view_background"/>
What could the problem be?
EDIT:
whole XML (It doesn't show all of the code. Here is also pastebin:http://pastebin.com/8rJvSx7V):
<?xml version="1.0" encoding="utf-8"?>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/story_view_background"/>
<RelativeLayout
android:id="#+id/story_view_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="50px">
<ImageView
android:id="#+id/story_view_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/story_view_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="13sp"
android:layout_below="#+id/story_view_image"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:gravity="center_horizontal"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
</FrameLayout>
try to set android:layout_height="150dp" for your CardView (don't use px!). Its child FrameLayout is unnecesarry (CardView is extending FrameLayout and have set same attributes set), remove it.
It's not so well written, all your Views have match_parent set for height, besides Image and Text views... Your item is probably trying to fit RecyclerView height in this case ("whole screen") and is measured without image at first time (Picasso async downloading, setting image when view is already measured). But when you inflate your View again (scroll and recycle) new list item will be measured differently, because Picasso will insert your image "in runtime", no need to async fetching (cache)

Android VideoView hides Layout Elements

I have the following layout (cut down to a minimal example)
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView
android:id="#+id/videoView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<EditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/free_text_default_bg"
android:gravity="center_horizontal"
android:padding="#dimen/free_text_padding"
android:text="background element is a video view" />
</RelativeLayout>
The problem is, that if I move the EditText around (it has a drag listener attached to it), it dissapears at a certain point of the screen as you can see in this screenshot.
The problem seems to only appear when I have a VideoView. Even if I don't show a video.
When I replace it with e.g. an ImageView there is no problem at all.
So my question is, what's happening and how can I resolve this?
Thanks for your time!
UPDATE 1: This only happens if the VideoView has
android:layout_height="match_parent"
when I set it to some "dp" value everything works just fine...
I did not find a solution to my question jet but I have found a workaround:
Once the layout is finished, I get the height from the parent container, subtract 1px and set this as new height for the video view.
The 1px is barely visible...
Here is the code:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
ViewGroup.LayoutParams layoutParams = videoView.getLayoutParams();
layoutParams.height = parentView.getHeight() - 1;
videoView.setLayoutParams(layoutParams);
}

How can I change the color of selected item from ListView?

I have created an android project in which i have a list view with 6 items.
I want that every time I select any item from the list, it gets a colour orange which stays until I press button submit.
the code is:
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.SafeWalkApp.SecondActivity" >
<ListView
android:id="#+id/sampleListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="5dp"
android:background="#android:color/transparent"
android:cacheColorHint="#android:color/transparent"
android:divider="#CCCCCC"
android:dividerHeight="1dp"
android:entries="#array/vol_list" >
</ListView>
<Button
android:id="#+id/onsubmit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="#string/submit" />
</RelativeLayout>
this is my xml code.
I have tried adding the color to color.xml but that is showing me an error message and basically it is for the backgroung. So please help me out on this.
Well if you are using a custom listview and had an item set by custom adapter then you can change the color of the listview item in
nList = (ListView) findViewById(android.R.id.yourlistname);
nList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
}
});
In above function nList is the list in which you want to make change and in its on click listner you can get the selected item view as in its parameters as View arg1 and from that you can get the linear layout and its all other controls and make changes to any control color, text etc as you want
get the view in here and set any color you want by getting the view and setting its background etc.
I can not write the whole code here but I hope you get my?
You must create state drawable colors. And some xml.files to define different colors depending on the state of your row.
Maybe this can help you.
How to change color of ListView items on focus and on click
Android LinearLayout with color resource: What am I doing wrong?
Make a class that contains all the info that is needed for your adapter item + a boolean variable, that you are going to check in adapters getView, if the variable is going to be true, change the color to orange else normal color.
in onItemClick find the position of the correct object in the list that you gave to your adapter and change its boolean value.
after that refresh the adapters referenced list.
Call notifyDataSetChanged() on your adapter. Now according to point(1.) the adapter is going to check the boolean value of the item and change its color to orange.

ListView headers without list item separators

I'm currently writing an Android app that uses ListView with headers. It works okay, but not really as I want. Every item in ListView has 1-2px separator at the top and bottom of it. So does the header - and that's the problem. It does not look very pretty...
The interesting part is that system apps (like Settings, for instance) does not have such problem.
Here's my example adapter:
setListAdapter(new BaseAdapter() {
#Override
public int getCount() {
return 10;
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = ((LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(i % 3 == 0 ? R.layout.list_header : android.R.layout.simple_list_item_1, viewGroup, false);
((TextView)v.findViewById(android.R.id.text1)).setText("test");
return v;
}
});
And list header layout file:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello, World"
style="?android:attr/listSeparatorTextViewStyle">
</TextView>
So the question is: how to get rid of the item separators between headers and regular items, just like, for example, Settings app does?
EDIT:
After reading the answers, I want to clear one thing up. I do not want to remove separators completely. I want to remove them only between the header items and regular items. Also, half-measures like "removing separators completely and adding them on some items" do not satisfy me, too.
It seems that you have to use a custom item view for dividers and a little workaround. Let me explain how to manage this:
Do not use the default dividers, remove it.
Create a custom layout with a View at bottom to be the subline for headers.
Create a custom layout with a View at top to have the divider for items.
Then, the two types of dividers will be glue to make only one subline for header part, so dividers should have the same height in order to make a good subline. This will avoid to have a divider above the header sections but keeping the dividers for items list.
Therefore, let me show some code to achieve it. First, don't forget to avoid default divider on the ListView:
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#null"
android:dividerHeight="0dp"/>
Create an item layout with a divider at top set to 1dp (or whatever):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- this is the divider for items -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/darker_gray"/>
<!-- and the rest of item's content in another ViewGroup -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher"/>
<TextView
android:id="#+id/item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:textColor="#android:color/white"/>
</LinearLayout>
</LinearLayout>
Finally, the header layout with a divider at bottom (with the same height as item's divider):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/item_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
style="?android:attr/listSeparatorTextViewStyle"/>
<!-- this is the ("half-")divider for header section -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/darker_gray"/>
<!-- this view above will be merged with item's dividers -->
</LinearLayout>
And it gives this result:
Remove the style you have set for the header TextView
Create your own custom style with required divider and set it to TextView
<style name="CustomListSeperatorTextViewStyle" parent="Widget.TextView.ListSeparator">
<item name="android:background">#drawable/your_own_here</item>
Seperator is due to the style you have set with the textview, just remove the style hope this will work.
I just found these parameters that seem to be what you need, you can try adding them in your ListView:
android:headerDividersEnabled="false"
android:footerDividersEnabled="false"
The documentation is available here and indicates:
When set to false, the ListView will not draw the divider after each header view. The default value is true.

Another Fragment on top op a Mapview (SupportMapFragment)

Im adding another Fragment to the screen. This screen already has en MapView in a SupportMapFragment so the added Fragment should be on top of the MapView. This new view cover like 2/3 of the screen and a big part of the Map but when I scroll on the View it scrolls the MapView underneath. This is not what i expected because the new View is added on top of the MapView. The new view exist of a relative layout containing a ImageView which wraps it contents. So when scrolling on the imageview (which has totally no functionality) it scrolls the MapView. Can anyone explain why this happens and if possible, provide me with a solution?
EDIT:
basically i have a MapView which fills the whole screen. This code sets up my mapview:
public void setUpMapIfNeeded(int satelliteMode, LatLng startPoint, float zoomLevel) {
// Do a null check to confirm that we have not already instantiated the map.
if (mapView == null) {
// Try to obtain the map from the SupportMapFragment.
mapView = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapview))
.getMap();
// Check if we were successful in obtaining the map.
if (mapView != null) {
setUpMap(satelliteMode, startPoint, zoomLevel);
}
}
}
private void setUpMap(int satelliteMode, LatLng startPoint, float zoomLevel) {
// more settings
}
Then when a user clicks a marker a fragment must be shown on top of the mapview.
public void createDetailView() {
detailView = new DetailViewFragment();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.viewLayout, detailView).commit();
fragmentManager.executePendingTransactions();
}
This all works fine. The view is shown (which is about 2/3 of the whole screen) but user can scroll the map when swiping the detailview. The detailview consist of a relative layout with a lot of text and buttons:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="45sp">
<!-- a lot of text and buttons here -->
</RelativeLayout>
So I still havent found a proper way to deal with this. Instead I just disabled all touches and clicks on the mapview when another view is on top of the mapview which btw works ok.
Just in case it might still be relevant, the way I've handled this kinds of layouts (one view appearing "on top of" another) is to use LinearLayout instead of a RelativeLayout in the following way:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<SomeView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<PopOutView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:visibility="gone" />
</LinearLayout>
In your case the map would be that SomeView and the relative layout the PopOutView. Then in the code you would just call popOutView.setVisibility = View.VISIBLE whenever you would like it to show up. It shrinks the first view instead of being drawn on top (thus having a bit different visual effect) but at least this way the touch events should go to the right view.
Set the fragment's layout clickable property to true. It will stop the touch events from propagating down.
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFF"
android:clickable="true">
</FrameLayout>

Categories