Support ListFragment issue - android

I'm currently using a ListFragment together with an ExpandableListView to show some data backed by a SimpleCursorTreeAdapter. Everything works fine, but I recently switched to the support.v4 package, to make use of the ViewPager class to swipe between tabs. Swiping and all the other classes that now use the support.v4.Fragment work fine, but my ListFragment has stopped working.
There are no exceptions thrown, but the ListFragment simply doesn't show any items.
This is the code for the ListFragment:
public class VisuTextFragment extends ListFragment {
private Storage mStorage;
private int mFilterSensortype;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mStorage = Storage.newSQLiteDatabase(getActivity());
mFilterSensortype = -1;
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.l_visu_text, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
fillData();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.textvis, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_filter:
final Dialog dialog = new Dialog(getActivity());
dialog.setTitle("Filter by sensor type");
dialog.setContentView(R.layout.l_dialog_filter);
Button ok = (Button) dialog.findViewById(R.id.filter_ok);
ok.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int filter = Integer.parseInt(((EditText) dialog.findViewById(R.id.et_filter)).getText().toString());
mFilterSensortype = filter;
fillData();
dialog.dismiss();
}
});
Button cancel = (Button) dialog.findViewById(R.id.filter_cancel);
cancel.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.cancel();
}
});
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dialog.show();
break;
}
return true;
}
#Override
public void onResume() {
super.onResume();
fillData();
}
public void fillData() {
Log.d("VisuTextFragment", "fillData()");
Cursor cursor;
if (mFilterSensortype == -1)
cursor = mStorage.queryAllAsCursor();
else
cursor = mStorage.query(mFilterSensortype);
TextVisCursorAdapter adapter = new TextVisCursorAdapter(
getActivity(),
cursor,
R.layout.l_visu_text_group,
new String[] { Storage.ELEMENT_ID, Storage.ELEMENT_ENTRIES_DATE, Storage.ELEMENT_ENTRIES_LATITUDE, Storage.ELEMENT_ENTRIES_LONGITUDE, Storage.ELEMENT_ENTRIES_SENSORTYPE },
new int[] { R.id.id, R.id.date, R.id.latitude, R.id.longitude, R.id.sensortype },
R.layout.l_visu_text_child,
new String[] { Storage.ELEMENT_MEASUREMENTS_VALUE },
new int[] { R.id.value });
ListView lv = (ListView) getListView();
ExpandableListView elv = (ExpandableListView) lv;
elv.setGroupIndicator(null);
elv.setAdapter(adapter);
}
}
And this is the layout that I'm using (don't know if that helps):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/id"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="#string/date"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="#string/latitude"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="#string/longitude"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/sensortype"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ExpandableListView android:id="#+id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:transcriptMode="normal"/>
<TextView android:id="#+id/android:empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/no_entries"/>
</LinearLayout>
</LinearLayout>
Just FYI: The TextView's in the layout file are shown, but the list itself is just missing. Not even the TextView for an empty list is shown.
Hope you can help.
EDIT: I have checked for the ExpandableListView's width and height via their corresponding methods and both return a value of 0. Its getCount() method returns 347. So the View definitely exists and is filled properly, but it is for some weird reason just not drawn to the screen.
EDIT2: Ok I fixed the problem. The problem was that the LinearLayout that hosted the TextViews on top of the actual list had its layout_height attribute set to fill_parent, which strangely was no issue for the non-support version as well as the composer in eclipse, since they both worked that way and I didn't even notice that it was set to fill_parent.

getListView() in a ListFragment is specifically looking for a listview id of #id/android:list. I'm not sure that adding the "+" in there like you did would have an effect or not, but it's the first thing I would try.
You also note you switched to the support library... did you switch all the appropriate method calls? For example, instead of getFragmentManager you would need to use getSupportFragmentManager and instead of using an Activity to control the fragments, you would need to use FragmentActivity, etc.

I think that that its butter to use android:id="#android:id/list" instead of android:id="#+id/android:list", also, in your case its really useless to extend ListFragment, just use Fragment and use findViewById for your expandableList.
Can you change:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
to:
public void onActivityCreated(Bundle aSavedInstanceState) {
super.onActivityCreated(aSavedInstanceState);
fillData();
}
make sure that your fillData method is called.

Ok I fixed the problem. The problem was that the LinearLayout that hosted the TextViews on top of the actual list had its layout_height attribute set to fill_parent, which strangely was no issue for the non-support version as well as the composer in eclipse, since they both worked that way and I didn't even notice that it was set to fill_parent.

Related

Trouble editing TextView within Fragment

So I am still fairly new to working with Android Studio and everything in it. I have been stuck on trying to get fragments to communicate directly with each other. Here I'm simply just trying to set the TextView text element within one of my fragments. I have looked for hours and tried a lot, but I'm not sure what to do. Also, I am implementing my fragments through code in a FrameLayout.
Here is my fragment whose text value I'm trying to edit:
public class ReceivingFrag extends Fragment {
TextView sender;
public void updateText(String text) {
sender.setText(text);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag_sender, container, false);
sender = (TextView) v.findViewById(R.id.sender);
return v;
}
}
I believe my root problem is that getView() and sender both return Null. I also understand that fragments are not technically views, but rather aid in the layout of views and ViewGroups. Any help is appreciated.
Not sure if it helps, but this is the method that calls the updateText() method within the ReceivingFrag class.
public void sendText(String text){
ReceivingFrag frag = new ReceivingFrag();
getSupportFragmentManager().beginTransaction().add(R.id.receiving_container, frag).commit();
getSupportFragmentManager().executePendingTransactions()
frag.updateText(text);
}
**Edit:
This is my MainActivity class that is calling and creating the Fragment:
public class MainActivity extends AppCompatActivity implements SendingFragment.TextClicked {
private static final String TAG = MainActivity.class.getSimpleName();
public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] myStringArray = {"Hello", "Nice To See You", "Bye"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, myStringArray);
ListView listView = (ListView) findViewById(R.id.mobile_list);
listView.setAdapter(adapter);
sendText("Hello");
}
#Override
public void sendText(String text){
ReceivingFrag frag = new ReceivingFrag();
getSupportFragmentManager().beginTransaction().add(R.id.receiving_container, frag).commit();
getSupportFragmentManager().executePendingTransactions();
frag.updateText(text);
}}
**Edit 2:
This is the MainActivity layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/apk/tools"
xmlns:tools2="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1">
<EditText android:id="#+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="#string/edit_message"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="sendMessage"
android:text="#string/button_send"/>
</LinearLayout>
<ListView android:id="#+id/mobile_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/receiving_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></FrameLayout></LinearLayout>
And this is the layout for the Fragment:
<?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:id="#+id/sender"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/frag_sender"
android:background="#color/gray"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"/></LinearLayout>
Solution:
So as mentioned below, the runtime error was fixed by adding
#Override
protected void onResume() {
super.onResume();
sendText("hello");
}
to the MainActivity class. After reading from https://developer.android.com/guide/components/fragments.html#Lifecycle
I think the statement
"Once the activity reaches the resumed state, you can freely add and remove fragments to the activity. Thus, only while the activity is in the resumed state can the lifecycle of a fragment change independently."
best explains the situation and why the error initially occurred.
If you instead put the sendText() in your onResume() like this,
#Override
protected void onResume() {
super.onResume();
sendText("Hello");
}
It will not give you the Null Pointer Exception. The fragment is still null when you call on it from onCreate().
Change your Fragment to this:
public class ReceivingFrag extends Fragment {
private TextView sender;
public void updateText(String text) {
sender.setText(text);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag_sender, container, false);
sender = (TextView) v.findViewById(R.id.sender);
return v;
}
}
and in your activity, before calling the updateText method, make sure the fragment transaction has executed by doing:
public void sendText(String text){
ReceivingFrag frag = new ReceivingFrag();
getSupportFragmentManager().beginTransaction().add(R.id.receiving_container, frag).commit();
getSupportFragmentManager().executePendingTransactions();
frag.updateText(text);
}

Android PullToRefesh library customize loading pulling/refreshing image

I am using com.handmark.pulltorefresh.library.PullToRefreshListView. By default it shows:
But I want pulltorefresh images/desing as following:
Here is xml i am using:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.handmark.pulltorefresh.library.PullToRefreshListView
android:id="#+id/lv_Inbox"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:divider="#19000000"
android:dividerHeight="4dp"
android:fadingEdge="none"
android:fastScrollEnabled="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:scrollbars="none"
android:smoothScrollbar="true"
ptr:ptrAnimationStyle="flip"/>
<ProgressBar
android:id="#+id/progress_LoadingList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="visible" />
<TextView
android:id="#+id/lbl_NoMessagesFound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="gone" />
</RelativeLayout>
The animation style controls how the Pull-to-Refresh functionality is presented to the user. The different options are:
Rotate (default)
Flip
Customizing icon and custom labels
And you want flip,So in your xml view
<com.handmark.pulltorefresh.library.PullToRefreshListView
xmlns:ptr="http://schemas.android.com/apk/res-auto"
android:id="#+id/pull_to_refresh_listview"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
ptr:ptrAnimationStyle="rotate"
/>
Change
ptr:ptrAnimationStyle="rotate"
to
ptr:ptrAnimationStyle="flip"
And add xmlns:ptr="http://schemas.android.com/apk/res-auto" in com.handmark.pulltorefresh.library.PullToRefreshListView tag as
<com.handmark.pulltorefresh.library.PullToRefreshListView
xmlns:ptr="http://schemas.android.com/apk/res-auto"
android:id="#+id/lv_Inbox"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:divider="#19000000"
android:dividerHeight="4dp"
android:fadingEdge="none"
android:fastScrollEnabled="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:scrollbars="none"
android:smoothScrollbar="true"
ptr:ptrAnimationStyle="flip"/>
For more info see android-pull-to-refresh Customization
An advanced pull to refresh will help you to provide modern approach in your app.
It is very smooth and easy to implement. And it will support for the lower versions also (from v2.3). The below screen shot will recall the new kind of refresh.
UI part
Create an Android from your eclipse or Android studio.
In your activity layout add the SwipeRefreshLayout.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="#string/hello_world"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"/>
</ScrollView>
Note : It has only View inside the layout. Add the scrollView inside the SwipeRefresh layout to support pull to refresh. For ListView and GridView no need to add ScrollView inside SwipeRefreshLayout.
code part
Add the following lines in onCreate method of your Activity.
public class SwipeActivity extends Activity implements OnRefreshListener {
SwipeRefreshLayout swipeLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipe);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light);
}
#Override
public void onRefresh() {
// TODO Auto-generated method stub
new Handler().postDelayed(new Runnable() {
#Override public void run() {
swipeLayout.setRefreshing(false);
}
}, 5000);
}
}
swipeLayout.setOnRefreshListener(this); sets Refresh listener for your layout.
Loading color schemes are adding using
swipeLayout.setColorScheme(android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light);
To stop the loading progress swipeLayout.setRefreshing(false);.
Thats it. Run your appplicaton you also did the new pull to refresh.
SWIPE TO REFRESH WITH LISTVIEW
Here I add an example of pull to refresh with listview. Then you will know how easy it is to integrate.
Create a new Activity in your application, add the listview in your SwipeRefreshLayout.
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
Declare and initialze variables for listview, adapter, String array for list items. Below codes will add the list items from array when you do pull to refresh.
public class SwipeActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipe);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.swipe, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment implements OnRefreshListener {
SwipeRefreshLayout swipeLayout;
ListView listView;
ArrayAdapter adapter;
ArrayList< String> arrayList;
String [] array = new String[]{"Apple","Batman","captain America","darkknight"};
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_swipe, container, false);
swipeLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
listView= (ListView) rootView.findViewById(R.id.listview);
adapter = new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1, appendData());
listView.setAdapter(adapter);
return rootView;
}
#Override
public void onRefresh() {
// TODO Auto-generated method stub
new Handler().postDelayed(new Runnable() {
#Override public void run() {
appendData();
adapter.notifyDataSetChanged();
swipeLayout.setRefreshing(false);
}
}, 5000);
}
private ArrayList appendData(){
if(arrayList==null)
arrayList = new ArrayList();
for (String items : array) {
arrayList.add(items);
}
return arrayList;
}
}
}
Note: I have used appcompat library to support the Actionbar for lower versions. So My Activity extends ActionBarActivity. In updated ADT version of eclipse and studio, your application will be created with fragment concepts. So application is created with instant fragment concepts.
I guess you like this example. Try it yourself and get practiced.
Happy coding :-).
And resultant screen, see this:
And for your existing program, use this link

Android - Popup menu when list item view pressed?

i would like to implement a popup menu similar to google's play store as shown below.
so basically from what i understand, i'll need an activity and a layout for this activity with a listview defined in it. i need to create my custom adapter. also, i need to create a list layout would contain the information and a view (with the 3 dots) that will serve as the button to launch the popup menu? the issue that i'm seeing here is that how do i create a listener for this view only and how do i reference the value for that specific list item in the list view.
i don't have any code available yet as i haven't started anything related to this. i'm currently getting info in theory for now but if required i will create a sample code.
thanks.
Using popup menu it's quite simple to create a menu with these three steps:
1 - Add a click listener to the menu button using OnClickListener or as i prefer from the layout xml:
<ImageButton android:id="#+id/menu_button" android:onClick="showMenu" ... />
2 - Create the menu layout menu_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/item_settings"
android:showAsAction="ifRoom|withText"
android:title="Settings"
android:visible="true"/>
<item
android:id="#+id/item_about"
android:showAsAction="ifRoom|withText"
android:title="About"
android:visible="true"/>
</menu>
3 - Create a popup menu, inflate the xml layout and show it:
public void showMenu (View view)
{
PopupMenu menu = new PopupMenu (this, view);
menu.setOnMenuItemClickListener (new PopupMenu.OnMenuItemClickListener ()
{
#Override
public boolean onMenuItemClick (MenuItem item)
{
int id = item.getItemId();
switch (id)
{
case R.id.item_settings: Log.i (Tag, "settings"); break;
case R.id.item_about: Log.i (Tag, "about"); break;
}
return true;
}
});
menu.inflate (R.menu.menu_layout);
menu.show();
}
ActionBarCompat List PopupMenu implementation is here (with back port available because it uses ABC)!
You can also get this sample from Github or from SDK (Mr.Morgan commented below)
/sdk/samples/android-19/ui/ActionBarCompat-ListPopupMenu. Make sure to
install Samples for SDK under Android 4.4.2 (API 19)
You can use like this:
public class MainActivity extends Activity {
ListView listView_Actions;
ArrayList<String> actionsArrayList;
Button btn_ViewPopUp;
ArrayAdapter<String> actionsAdapter;
static final int CUSTOM_DIALOG_ID1 = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_ViewPopUp=(Button) findViewById(R.id.btn_ViewPopUp);
actionsArrayList=new ArrayList<String>();
actionsArrayList.add("Action 1");
actionsArrayList.add("Action 2");
}
#Override
protected void onStart() {
super.onStart();
btn_ViewPopUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDialog(CUSTOM_DIALOG_ID1);
actionsAdapter = new MyCustomBaseAdapter(getApplicationContext(), R.layout.list_actions, actionsArrayList);
listView_Actions.setAdapter(actionsAdapter);
}
});
}
#Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
switch (id) {
case CUSTOM_DIALOG_ID1:
dialog = new Dialog(MainActivity.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setContentView(R.layout.list_actions);
listView_Actions = (ListView) dialog.findViewById(R.id.listView_Actions);
break;
}
return dialog;
}
class MyCustomBaseAdapter extends ArrayAdapter<String>
{
public MyCustomBaseAdapter(Context context, int textViewResourceId, ArrayList<String> actionsArrayList) {
super(context, textViewResourceId,actionsArrayList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.action_list_cell, null);
final TextView lblContactAction;
lblContactAction = (TextView) v.findViewById(R.id.txtContactAction);
lblContactAction.append(actionsArrayList.get(position));
return v;
}
}
}
Now XML files:
action_list_cell.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:orientation="vertical"
android:background="#android:color/background_light" >
<TextView
android:id="#+id/txtContactAction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textSize="18dp"
android:textColor="#android:color/black" />
</LinearLayout>
list_actions.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:orientation="vertical"
android:background="#drawable/rounded_corner_top">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#DB6A16"
android:orientation="vertical"
android:paddingBottom="2dp"
android:paddingLeft="2dp"
android:paddingRight="2dp" >
<ListView
android:id="#+id/listView_Actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff" >
</ListView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
first of all you need to make your custom adapter with a view that has the 3 dots.
then in the getView() or newView() method you set the listener to the 3 dots image.
i think that PopupMenu is what you are looking for, it's is supported since API 11.
if you want to support also earlier version of the API you can use PopupMenu class provided by the support library v7.
the usage is pretty straight forward.
you define it with the id of the view you want the menu to show next to, and then you can directly inflate a menu resource there as if it was a common menu.
Now showDialog is deprecated, use PopupMenu instead
And AppCompat PopupMenu f you want to support version before V11
public class MainActivity extends Activity {
Button button1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Creating the instance of PopupMenu
PopupMenu popup = new PopupMenu(MainActivity.this, button1);
//Inflating the Popup using xml file
popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
//registering popup with OnMenuItemClickListener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(MainActivity.this,"You Clicked : " + item.getTitle(),Toast.LENGTH_SHORT).show();
return true;
}
});
popup.show();//showing popup menu
}
});//closing the setOnClickListener method
}
}
You have to set the Listener of the Button in the getView()-Method of your List-Adapter.
In this getView()-Method you assign a Layout to one List-Item. if you have done this, you just have to set the Listener on this View (Button), and handle the onClick() Event.
Not sure if i understand you correctly but you can trigger this method to open a pop up dialog with a listview.
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Title if Any");
builder.setItems(R.array.listoptions, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int itemClicked) {
String[] option_array = getResources().getStringArray(R.array.listoptions);
String optionSelected = option_array[itemClicked];
}
});
return builder.create();
}
See Adding a List
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="listoption">
<item>Install</item>
<item>Add to listview</item>
</string-array>
</resources>
Hope this helps.

DialogFragment not floating, acts embeded or as another fragment

I have this app, that I created a custom dialog for. I must of goofed something up cause while the .show call on the dialog does indeed bring it up, it looks like a whole new fragment and it is not floating but instead replacing the ui with its contents. I did see in their help for DialogFragment:
http://hi-android.info/docs/reference/android/app/DialogFragment.html#Lifecycle
that one can embed a dialog as a regular fragment or not. Though I am not doing anything to do this so I cannot figure out why its acting like an embedded fragment and not floating. After thinking on it, is it the way I defined my XML definition? The dialogfragment example above didn't really give a definition for the xml layout, so maybe that is where my issue is? (Even added the gravity to the xml file, still no dice)
My xml definition for this Dialog is here:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textSize="20sp"
android:text = "Location:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"/>
<Spinner
android:id="#+id/location_spinner"
android:layout_width = "450sp"
android:layout_height="wrap_content"/>
<!-- fill out the data on the package total cost etc -->
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:id="#+id/location_dlg_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Okay"/>
<Button android:id="#+id/location_dlg_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"/>
<Button android:id="#+id/location_dlg_new"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create new..."/>
</LinearLayout>
</LinearLayout>
Like I said displays just fine, the code for the fragment:
package com.viciousbytes.studiotab.subactivities.dialogfragments;
import ... ...
public class LocationPicker extends DialogFragment {
ArrayList<Location> mLocations;
public static LocationPicker newInstance()
{
LocationPicker loc = new LocationPicker();
return loc;
}
private void setLocations(ArrayList<Location> loc)
{
mLocations=loc;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Pick a style based on the num.
int style = DialogFragment.STYLE_NORMAL, theme = android.R.style.Theme;
setStyle(style, theme);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.location_dialog, container, false);
Spinner spinner = (Spinner)v.findViewById(R.id.location_spinner);
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(v.getContext(), android.R.layout.simple_spinner_item, mLocations);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
if(mLocations==null)
spinner.setPrompt("No Locations");
else
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new LocationSelectedListener());
// Watch for button clicks.
Button newBtn = (Button)v.findViewById(R.id.location_dlg_new);
newBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// When button is clicked, call up to owning activity.
//create new start that activity...
}
});
// Cancel do nothing dismissthis
Button cancelBtn = (Button)v.findViewById(R.id.location_dlg_cancel);
cancelBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// When button is clicked, call up to owning activity.
//create new start that activity...
}
});
// okay button means set listener with the selected location.
Button okBtn = (Button)v.findViewById(R.id.location_dlg_ok);
okBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// When button is clicked, call up to owning activity.
//create new start that activity...
}
});
return v;
}
}
It is called from a fragment itself? though does that matter? because I am calling a TimePIckerDialog and a DatePickerDialog and those work fine, but my calling code from my other fragment is:
void showLocationDialog() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("locpicker");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
// Create and show the dialog.
DialogFragment newFragment = LocationPicker.newInstance();
newFragment.show(ft, "locpicker");
}
Your constructors are wrong. Try to have just one static method newInstance to instantiate the fragment for all cases and use a Bundle to store the arguments that you want to use in the fragment. Refer to Basic Dialog section here and extend it to your case.

Android ListView - click handler not working

I'm still having a problem with a ListView click handler. The event is not being fired, so
I do not see the debugging message.
I want to use Activity instead of ListActivity
Here again is my code:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Capture our button from layout
//appState = ((MyApp)getApplicationContext());
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//requestWindowFeature(Window.FEATURE_LEFT_ICON);
setContentView(R.layout.listr);
//setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.fishicon);
setupDB();
populateList3();
ListView lv = (ListView) findViewById(R.id.list);
// lv.setClickable(true);
lv.setOnItemClickListener(new OnItemClickListener() {
//#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(ListRecords.this,"Clicked!", Toast.LENGTH_LONG).show();
}
});
Here is the XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:orientation="vertical"
android:gravity="center"
android:layout_height="fill_parent">
<!--Put form controls here-->
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="400dp" />
<Button
android:id="#+id/previousbutton"
android:gravity="center_horizontal"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:text="Previous Menu"/>
</LinearLayout>
I cannot figure out why the click listener is not working.
Thanks
Mike
Don't use inline listeners unless you're sure of how to use them - they can go out of scope and cause a variety of problems.
Try this...
public class MyActivity extends Activity
implements AdapterView.onItemClickListener {
#Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listr);
ListView lv = (ListView) findViewById(R.id.list);
lv.setOnItemClickListener(this);
// Do whatever else you need to do
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Do whatever
}
}
I would uncomment the #Override. It is there to guarantee that your signature matches the method you're trying to override.
If your method signature is correct, then I suspect the problem lies in populateList3(). Could you post that code as well?
You're not registering the list for the context menu: http://developer.android.com/reference/android/app/Activity.html#registerForContextMenu(android.view.View)

Categories

Resources