How to implement on item click listener properly in such a case when one .xml file stands for general view of grid and another one for customized item within that grid?
general view fragment_main.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">
<GridView
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:stretchMode="columnWidth"
android:numColumns="2"
/>
and view of Item cosists of picture and textview gridview_item.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">
<com.myapp.gridview.SquareImageView
android:id="#+id/picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
/>
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:layout_gravity="bottom"
android:textColor="#android:color/white"
android:background="#55000000"
/>
</FrameLayout>
where is it needed to write android:onClick="" - in fragment_main or gridview_item? Are there any other needed properties of gridview to be enabled?
Thank for advices.
if you are dealing with BaseAdpater or ArrayAdapter in that class you will be having getView method which returns View object you can simply write a setOnClickListerner on that view(converview)
look at the following code this may help you
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=inflater.inflate(R.layout.group_row, null);
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// your logic goes here
}
});
return view;
}
Related
I have a recyclerview list. Each item in the recyclerview contains the following layout. Later when one clicks on the sample1 id, then sample3.xml should get inserted inbetween sample1 and sample2. For that I have created a linearlayout with id insertat in this layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="40dp"
android:id="#+id/sample1"
android:text="Sample1"/>
<LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/insertat">
</LinearLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="40dp"
android:id="#+id/sample2"
android:text="Sample2"/>
</LinearLayout>
onclicking id sample1 I want to insert a layout file sample3.xml inside linearlayout id insertat.
sample3.xml is as follows
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/toinsert">
<TextView
android:layout_width="fill_parent"
android:layout_height="40dp"
android:text="Sample1"
android:id="#+id/sample3"/>
</LinearLayout>
How can I achieve this in recyclerview code.
I did not get exact requirement but , if you want just visible the view after on click, you can keep your layout by merge both as like below and can visible and invisible based on click event.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="40dp"
android:id="#+id/sample1"
android:text="Sample1"/>
<LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:id="#+id/insertat">
<TextView
android:layout_width="fill_parent"
android:layout_height="40dp"
android:text="Sample1"
android:id="#+id/sample3"/>
</LinearLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="40dp"
android:id="#+id/sample2"
android:text="Sample2"/>
</LinearLayout>
LinearLayout layout = (LinearLayout)findViewbyId(R.id.insertat);
mKeepPlayingButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
layout.setVisibility(View.visible);
}
});
First get a reference of the insertat:
LinearLayout insertAtView = (LinearLayout) findViewById(R.id.insertat);
Inflate sample3 view:
View sample3View = getLayoutInflater().inflate(R.layout.sample3, insertAtView, false);
Then add sample3 to insertat:
insertAtView.addView(sample3View);
Full code:
findViewById(R.id.sample1).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LinearLayout insertAtView = (LinearLayout) findViewById(R.id.insertat);
View sample3View = getLayoutInflater().inflate(R.layout.sample3, insertAtView, false);
insertAtView.addView(sample3View);
}
});
My activity_main.xml is evenly split vertically 3 ways with LinearLayout. I would like to fill the bottom LinearLayout with a ListFragment and populate it with data.
Currently, the ListFragment ignores the 3 LinearLayout and just places itself on top of them.
LstFragment.java
public class LstFragment extends ListFragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragmentlayout, container, false);
// Create an array of string to be data source of the ListFragment
String[] datasource={"English","French","Khmer","Japanese","Russian","Chinese"};
// Create ArrayAdapter object to wrap the data source
ArrayAdapter<String> adapter=new ArrayAdapter<String>(getActivity(),R.layout.rowlayout,R.id.txtitem,datasource);
// Bind adapter to the ListFragment
setListAdapter(adapter);
// Retain the ListFragment instance across Activity re-creation
setRetainInstance(true);
return rootView;
}
// Handle Item click event
public void onListItemClick(ListView l, View view, int position, long id){
ViewGroup viewg=(ViewGroup)view;
TextView tv=(TextView)viewg.findViewById(R.id.txtitem);
Toast.makeText(getActivity(), tv.getText().toString(),Toast.LENGTH_LONG).show();
}
}
MainActivity.java
public class MainActivity extends FragmentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LstFragment lstfragment=(LstFragment)getSupportFragmentManager().findFragmentByTag("lstfragment");
if(lstfragment==null){
lstfragment=new LstFragment();
FragmentTransaction transact=getSupportFragmentManager().beginTransaction();
transact.add(android.R.id.content,lstfragment,"lstfragment");
transact.commit();
}
}
}
activity_main.xml
<LinearLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:id="#+id/topSection">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Testing"
android:id="#+id/textView3" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:id="#+id/middleSection">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Yo"
android:id="#+id/textView2"
android:layout_gravity="center_horizontal" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:id="#+id/bottomSection">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="WhatUP"
android:id="#+id/textView"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</LinearLayout>
There are two more simple .xml layout files called fragmentlayout.xml which contains a simple ListView #id/android:list and a rowlayout.xml which has a single TextView #id/textitem.
Replace
android:layout_height="fill_parent"
with this line
android:layout_height="0dp"
inside all the three child linear layouts
Reason
android.R.id.content gives you the root element of a view, without having to know its actual name/type/ID. That's why your Fragment is appearing at the top of everything.
You are trying to add your Fragment to wrong container here
transact.add(android.R.id.content,lstfragment,"lstfragment");
Solution
Add this
<FrameLayout
android:layout_width="fill_parent"
android:id="#+id/fragment_container"
android:layout_height="fill_parent">
</FrameLayout>
after 3rd LinearLayout but before closing the root LinerarLayout
then change to
transact.add(R.id.fragment_container,lstfragment,"lstfragment");
Also,
in all of the LinearLayout use this android:layout_height="wrap_content"
I have a gridview that shows a list of images, and I implemented choice mode listener for this gridview. The problem is, when I press long click to select set of images, they are not highlighted..
item_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
android:id="#+id/photo"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:contentDescription="#string/media_thumbnail"/>
fragment_photos.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Empty View -->
<RelativeLayout
android:id="#+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<ImageView
android:id="#+id/download_arrow"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_centerInParent="true"
android:contentDescription="#string/downloads"
android:src="#drawable/ic_photo"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/download_arrow"
android:layout_centerInParent="true"
android:layout_marginLeft="32dp"
android:layout_marginRight="32dp"
android:gravity="center"
android:text="#string/no_media"/>
</RelativeLayout>
<!-- Photos List -->
<GridView
android:id="#+id/list"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="3"
android:paddingBottom="5dp"
android:choiceMode="multipleChoiceModal"
android:paddingTop="5dp"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp"
android:visibility="gone"/>
</RelativeLayout>
PhotosFragment.java
public class PhotosFragment extends Fragment
{
#Bind (R.id.list)
GridView mGridView;
private MediaGridAdapter mAdapter;
private ArrayList<File> mFiles;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_media, container, false);
ButterKnife.bind(this, view);
mGridView.setMultiChoiceModeListener(new MultiChoiceModeListener());
// set adapter and fetch files code ....
return view;
}
}
There is no magic highlight effect, you have to implement it yourself, example would be setting a foreground drawable which is a semi transparent gray.
I'm using this library for the fab implementation.
As you can see in this video, the fab position is changing when the fragment loads.
After debugging it, I found that the listview "setAdapter()" method causes the position change.
I don't have a clue why it's happening..
My layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:theme="#style/AppTheme.ActionBar" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/toolbar">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/sad_face"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/no_leagues" />
</LinearLayout>
</FrameLayout>
<com.melnykov.fab.FloatingActionButton
android:id="#+id/fab_new_league"
android:src="#drawable/ic_action_add"
app:fab_colorNormal="#color/orange"
app:fab_colorPressed="#color/redDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignBottom="#id/toolbar"
android:layout_marginBottom="-28dp"
android:layout_marginRight="28dp"
android:elevation="8dp"/>
</RelativeLayout>
My fragment
public class LeagueListFragment extends MyFragment {
#InjectView(android.R.id.list) ListView mListView;
#InjectView(android.R.id.empty) LinearLayout mEmpty;
public static Fragment newInstance() {
return new LeagueListFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_league_list, container, false);
ButterKnife.inject(this, view);
// Fetch league list and set up adapter
List<League> list = League.getAll();
mAdapter = new LeagueAdapter(getActivity(), list);
// Set up ListView
mListView.setEmptyView(mEmpty);
mListView.setDivider(new ColorDrawable(getResources().getColor(R.color.gray)));
mListView.setDividerHeight(2);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(this);
return view;
}
}
Margin changes in the runtime on pre-Lollipop because shadow mustn't be taken into account when margins are set.
Try to disable the shadow by :
fab:fab_shadow="false"
Fixing the issue is not expected for now.. (See makovkastar answer)
My drawer layout:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<!-- The navigation drawer -->
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:divider="#android:color/darker_gray"
android:dividerHeight="0.1dp"
android:listSelector="#drawable/drawer_list_selector"
/>
</android.support.v4.widget.DrawerLayout>
My list row:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/drawer_list_item_image"
android:contentDescription="Menu item image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:layout_gravity="center_vertical"
/>
<TextView
android:id="#+id/drawer_list_item"
android:layout_width="match_parent"
android:layout_height="48dp"
android:gravity="center_vertical"
android:textColor="#android:color/black"
/>
</LinearLayout>
Then the getView method in my custom adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View drawerRow = inflater.inflate(R.layout.drawer_row, parent, false);
TextView drawerRowText = (TextView) drawerRow
.findViewById(R.id.drawer_list_item);
ImageView drawerRowImage = (ImageView) drawerRow
.findViewById(R.id.drawer_list_item_image);
drawerRowText.setText(drawerRowTextValues[position]);
switch (position) {
case 0:
drawerRowImage.setImageResource(R.drawable.content_new_dark);
break;
case 1:
drawerRowImage.setImageResource(R.drawable.location_web_site_dark);
break;
case 2:
drawerRowImage.setImageResource(R.drawable.action_settings_dark);
break;
}
drawerRow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("drawer list item clicked...");
}
});
return drawerRow;
}
I can verify that the event is fired just can't see the list item colour changing(flashing) on click as opposed to when using ArrayAdapter for example.
Any ideas folks?
EDIT:
OK, I got almost the desired behaviour by adding a listSelector as follows:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed state. -->
<item android:drawable="#color/list_row_pressed_bg"
android:state_pressed="true"/>
</selector>
... adding that listSelector to my listView above with the following line:
android:listSelector="#drawable/drawer_list_selector"
My only problem now is that the pressed-state color doesn't fill in the whole item row in the list:
Change your LinearLayout's width to fill the row like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
...