Add a transparent fragment on top of an existing layout(android0 - android

I am trying to create a sort of a transparent tutorial which appears only
the first time. This is the fragment i have created. How do I add this on top of an existing layout
here's the code for the fragment
import android.app.Fragment;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import in.webblue.nuclity.Activity.Logs.SaveLog;
import in.webblue.nuclity.R;
import static android.content.Context.MODE_PRIVATE;
/**
* Created by Akshay on 15-06-2017.
*/
public class TutorialFragment extends Fragment {
private String Class_Name = "TutorialFragment";
private boolean ranBefore;
View topLevelLayout1;
View topLevelLayout2;
View myView;
String methodName = "onCreateView";
public static TutorialFragment newInstance() {
TutorialFragment f = new TutorialFragment();
return f;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myView = inflater.inflate(R.layout.tutorial_layout, container,
false);
topLevelLayout1=myView.findViewById(R.id.tutorial1);
topLevelLayout2=myView.findViewById(R.id.tutorial2);
if (!isFirstTime()) {
topLevelLayout1.setVisibility(View.INVISIBLE);
topLevelLayout2.setVisibility(View.INVISIBLE);
}
return myView;
}
private boolean isFirstTime()
{
try {
SharedPreferences preferences =
this.getActivity().getSharedPreferences("RanBefore", MODE_PRIVATE);
boolean ranBefore = preferences.getBoolean("RanBefore", false);
if (!ranBefore) {
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("RanBefore", true);
editor.commit();
topLevelLayout1.setVisibility(View.VISIBLE);
topLevelLayout2.setVisibility(View.INVISIBLE);
topLevelLayout1.setOnTouchListener(new
View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
topLevelLayout1.setVisibility(View.INVISIBLE);
topLevelLayout2.setVisibility(View.VISIBLE);
return false;
}
});
topLevelLayout2.setOnTouchListener(new
View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
topLevelLayout2.setVisibility(View.INVISIBLE);
return false;
}
});
}
}
catch (Exception e){
Log.e(getClass().getName(),"Method Name :"+methodName+ " "+ e.getStackTrace().toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
SaveLog.saveLog(getContext(),Class_Name,methodName,e.toString());
}
}
return ranBefore;
}
}
I need to add this on top of an existing layout

I think FrameLayout is the way to go here.
The secret of FrameLayout is how it layouts its children. Although normally designed to contain one item, it will happily stack up other element on top of each other. Thus FrameLayout is essentially a way to manipulate the Z-order of views on the screen
Here a thread about what a FrameLayout can do:
what does FrameLayout do?
So your Layout would look something like this:
<FrameLayout>
<Fragment/>
<LinearLayout>
// here is your normal layout
</LinearLayout>
</>

You could do it the following way.
This is your activity on top of which you need to add the fragment.
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical">
<LinearLayout
android:id="#+id/example_fragment_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
//YOUR LAYOUT
</LinearLayout>
<LinearLayout
android:id="#+id/example_fragment_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="EndFragment">
/*THE FRAGMENT YOU WANT TO SHOW. THE LOGIC TO SHOW THIS FRAGMENT
ONLY ONCE WILL HAVE TO BE IN THE ACTIVITY ON TOP OF WHICH YOU ARE
SHOWING THIS FRAGMENT*/
<fragment
android:id="#+id/example_fragment"
android:name="com.example.ExampleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</RelativeLayout>
Now what you should do is show this fragment only once. The onClick method to hide this fragment is as follows:
public void EndFragment(View view) {
example_fragment_parent.setVisibility(View.GONE);
}
You need to find this fragment in the onCreate() of your activity like below:
LinearLayout example_fragment_parent =
(LinearLayout)findViewById(R.id.example_fragment_parent);

Related

Buttons within a ListFragment not clickable

I have an Activity that lays out ListFragments side by side (as many as a user wants) in a HorizontalScrollView upon choosing an option in the ActionBar.
Each ListFragment item contains TextViews and a Button. A SimpleAdapter populates data for each item in every ListFragment.
The issue I am facing now is that the buttons in each list item do not respond to clicks. The layout can be summarized as follows: Button inside a ListFragment inside a FragmentActivity, going from the innermost child element to the parent at the root view.
I have spent many hours on this problem and I am unable to arrive at a solution to make the buttons respond to clicks. Some of the approaches I have used include obtaining the button's view and attaching onClickListeners, 2) implementing the OnClickListener interface for the ListFragment. I am also aware of the onInterceptTouchEvent method for a ViewGroup class, however my lack of experience with Android prevents me from arriving at a solution. Any guidance or direction towards solving this problem would be most appreciated.
Here is the code for the ListFragment:
package com.example.androidlistfragmenttest;
import java.util.ArrayList;
import java.util.HashMap;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.SimpleAdapter;
public class MyFragment extends ListFragment {
private ArrayList<HashMap<String,String>> arraylist;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_layout, container, false);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener(){
//THIS DOES NOT PRINT IN LOGCAT. BUTTON DOES NOT RESPOND TO CLICKS.
#Override
public void onClick(View arg0) {
Log.v("GODZILLA","ATOMIC BREATH");
}
});
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
arraylist = dataGenerator();
SimpleAdapter adapter = new SimpleAdapter(getActivity().getApplicationContext(), arraylist, R.layout.fragment_layout,new String[]{"KEY"},new int[]{R.id.text_id});
setListAdapter(adapter);
}
/*
* Method to populate an adapter's data list.
*/
public ArrayList<HashMap<String,String>> dataGenerator(){
HashMap<String,String> hashMap1 = new HashMap<String,String>();
hashMap1.put("KEY", "A");
HashMap<String,String> hashMap2 = new HashMap<String,String>();
hashMap2.put("KEY", "B");
HashMap<String,String> hashMap3 = new HashMap<String,String>();
hashMap3.put("KEY", "C");
HashMap<String,String> hashMap4 = new HashMap<String,String>();
hashMap4.put("KEY", "D");
HashMap<String,String> hashMap5 = new HashMap<String,String>();
hashMap5.put("KEY", "E");
ArrayList<HashMap<String,String>> arraylist = new ArrayList<HashMap<String,String>>();
arraylist.add(hashMap1);
arraylist.add(hashMap2);
arraylist.add(hashMap3);
arraylist.add(hashMap4);
arraylist.add(hashMap5);
return arraylist;
}
} //End of MyFragment
And this is the code for the Activity containing the Fragment(s):
package com.example.androidlistfragmenttest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends FragmentActivity {
private Stack<String> tagStack;
private Integer last_tag_number;
public MainActivity(){
last_tag_number = new Integer("0");
tagStack = new Stack<String>();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_fragment:
addColumn();
return true;
case R.id.remove_column:
removeColumn();
return true;
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
/*
* This method adds a fragment to the screen
*/
public void addColumn(){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyFragment fragment = new MyFragment();
fragmentTransaction.add(R.id.fragment_activity, fragment,tagGenerator());
fragmentTransaction.commit();
}
/*
* This method removes a fragment from the screen
*/
public void removeColumn(){
if(tagStack.size() != 0){
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tagStack.pop());
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragment);
fragmentTransaction.commit();
}
}
/*
* This function generates tags for each fragment that is displayed on the screen
* The tags pose as unique identifiers for each fragment
*/
public String tagGenerator(){
Integer tag_number;
if(last_tag_number.intValue() == 0){
tag_number = last_tag_number;
int temp = last_tag_number.intValue();
temp+=1;
last_tag_number = Integer.valueOf(temp);
}
else{
tag_number = new Integer(last_tag_number.intValue());
int temp = last_tag_number.intValue();
temp+=1;
last_tag_number = Integer.valueOf(temp);
}
String tag = tag_number.toString();
tagStack.push(tag);
return tag;
}
} //End of MainActivity
As well as the layouts for the FragmentActivity:
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:id="#+id/fragment_activity"
android:layout_width="fill_parent"
android:layout_height = "fill_parent"
android:orientation = "horizontal"
android:gravity="center"
>
</LinearLayout>
</HorizontalScrollView>
And the ListFragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1"
android:layout_margin="5dp"
android:descendantFocusability="blocksDescendants" >
<ListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/label"
android:layout_gravity="start"
/>
<TextView
android:id="#+id/text_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="end"
/>
</LinearLayout>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal" >
<Button
android:id="#+id/button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/button"
android:layout_margin="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
/>
</LinearLayout>
</LinearLayout>
The problem is that the ListItem is consuming the click and it is not getting passed to the button below.
You need to set the list items to inactive and handle the clicks yourself. In your custom Adapter add the following methods to disable the items (They override methods from BaseAdapter):
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
return false;
}
Edit: Here is a related question that may offer a better solution, it depends on your design.

How to create a custom drag shadow?

What I want to achieve:
I want to create a drag and drop functionality in Android. I'd like to use a specific layout (different from the dragged object itself) as a drag shadow.
What result I'm getting instead:
Neither of my approaches works as expected - I end up with no visible drag shadow at all (although the target does receive the drop).
What I tried:
I tried
inflating the drag_item layout in the activity, then passing it as an argument to the shadow builder's constructor
and
inflating the drag_item layout in the shadow builder's onDrawShadow method, then drawing it on the canvas
Layouts:
My activity layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.app.DragDropTestActivity"
tools:ignore="MergeRootFrame">
<TextView
android:id="#+id/tvReceiver"
android:text="Drop here"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/btnDragged"
android:layout_height="wrap_content"
android:text="Drag me"
android:layout_width="match_parent"/>
</LinearLayout>
The layout I want to use as a drag shadow:
dragged_item.xml
<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="wrap_content"
android:layout_height="wrap_content"
android:text="Dragged Item"/>
</LinearLayout>
Source code:
Here's the code with both approaches (represented by 1, BuilderOne and 2, BuilderTwo, respectively):
package com.example.app;
import android.graphics.Canvas;
import android.graphics.Point;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
public class DragDropTestActivity extends ActionBarActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drag_drop_test);
Button dragged = (Button) findViewById(R.id.btnDragged);
dragged.setOnTouchListener(
new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
if (event.getAction() != MotionEvent.ACTION_DOWN) {
return false;
}
LayoutInflater inflater = getLayoutInflater();
int approach = 1;
// both approaches fail
switch (approach) {
case 1: {
View draggedItem = inflater.inflate(R.layout.dragged_item, null);
BuilderOne builder = new BuilderOne(draggedItem);
v.startDrag(null, builder, null, 0);
break;
}
case 2: {
BuilderTwo builder = new BuilderTwo(inflater, v);
v.startDrag(null, builder, null, 0);
break;
}
}
return true;
}
});
}
My BuilderOne class:
public static class BuilderOne extends View.DragShadowBuilder
{
public BuilderOne(View view)
{
super(view);
}
#Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint)
{
super.onProvideShadowMetrics(
shadowSize,
shadowTouchPoint);
}
}
And BuilderTwo class:
public static class BuilderTwo extends View.DragShadowBuilder
{
final LayoutInflater inflater;
public BuilderTwo(LayoutInflater inflater, View view)
{
super(view);
this.inflater = inflater;
}
#Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint)
{
super.onProvideShadowMetrics(
shadowSize,
shadowTouchPoint);
}
#Override
public void onDrawShadow(Canvas canvas)
{
final View draggedItem = inflater.inflate(R.layout.dragged_item, null);
if (draggedItem != null) {
draggedItem.draw(canvas);
}
}
}
}
Question:
What do I do wrong?
Update:
Bounty added.
Kurty is correct in that you shouldn't need to subclass DragShadowBuilder in this case. My thought is that the view you're passing to the DragShadowBuilder doesn't actually exist in the layout, and therefore it doesn't render.
Rather than passing null as the second argument to inflater.inflate, try actually adding the inflated View to the hierarchy somewhere, and then passing it to a regular DragShadowBuilder:
View dragView = findViewById(R.id.dragged_item);
mDragShadowBuilder = new DragShadowBuilder(dragView);
v.startDrag(null, mDragShadowBuilder, null, 0);
EDIT
I'm aware that having the dragged_item view being rendered all the time isn't what you want, but if it works then at least we know where the problem is and can look for a solution to that instead!
Simply put it, you only need this:
private final class TouchListener implements View.OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
v.startDrag(ClipData.newPlainText("", ""), new View.DragShadowBuilder(v), v, 0);
}
return true;
}
}
(You don't necessarily need the BuilderOne and BuilderTwo class)

Handling touch Events for all layouts in xml

I have a linear layout which contains 5 linear layouts as its child. I want to handle the touch event for each child linear layouts. My layout looks like this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container">
<LinearLayout android:id="#+id/item1"
android:layout_width="match_parent"
style="#style/NavLinkItemContainer"
android:layout_height="wrap_content">
<TextView
style="#style/NaviLinkSelected"
android:text="First"/>
</LinearLayout>
<LinearLayout android:id="#+id/item2"
android:layout_width="match_parent"
style="#style/NavLinkItemContainer"
android:layout_height="wrap_content">
<TextView
style="#style/NaviLinks"
android:text="Second"/>
</LinearLayout>
<LinearLayout android:id="#+id/item3"
android:layout_width="match_parent"
style="#style/NavLinkItemContainer"
android:layout_height="wrap_content">
<TextView
style="#style/NaviLinks"
android:text="Third"/>
</LinearLayout>
<LinearLayout android:id="#+id/item4"
android:layout_width="match_parent"
style="#style/NavLinkItemContainer"
android:layout_height="wrap_content">
<TextView
style="#style/NaviLinks"
android:text="Fourth"/>
</LinearLayout>
<LinearLayout android:id="#+id/item5"
android:layout_width="match_parent"
style="#style/NavLinkItemContainer"
android:layout_height="wrap_content">
<TextView
style="#style/NaviLinks"
android:text="Fifth"/>
</LinearLayout>
</LinearLayout>
and My activity using the layout looks like
public class MainActivity extends Activity implements OnTouchListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("","ON TOUCH VIEW ######## "+v.getId());
return false;
}
}
When touching the child layouts, am not getting id(item1,item2...) in onTouch Event
Please advice.
For each layout you want to add touch listener, set onTouchListener.
for example,
LinearLayout l1 = (LinearLayout) findViewById(R.id.item2);
l1.setOntouchListener(this);
So for each ViewGroup you have to set the listener. The rest of things is already done by your. Int onTouch method you can handle touch or all ViewGroup
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (v.getId()) {
case R.id.item2:
do something
break;
case R.id.item3:
do something
break;
default:
break;
}
// if you want to consume the behavior then return true else retur false
}
Here is a solution to add an OnTouchListener to every element in the constraint, which will hide the keyboard every time you touch something but an object in the exclusion list.
import android.content.Context;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatCallback;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ConstraintLayout constraintLayout = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText editText = findViewById(R.id.editText);
//Get current ViewGroup. Might have to add an id in the layout xml for the constraint.
constraintLayout = findViewById(R.id.constraint);
//List of items that should be excluded
ArrayList<Integer> listOfExclusion = new ArrayList<>();
listOfExclusion.add(editText.getId());
addTouchListeners(listOfExclusion, constraintLayout);
}
/**
* #param excludedResIds ArrayList of list of ids that should be excluded by the addTouchListener
* #param parent ViewGroup containing the elements you want to lose focus off.
*/
void addTouchListeners(ArrayList<Integer> excludedResIds, ViewGroup parent){
parent.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
constraintLayout.requestFocus();
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
return false;
}
});
addTouchListener(excludedResIds,parent);
}
/**
* #param excludedResIds ArrayList of list of ids that should be excluded by the addTouchListener
* #param parent ViewGroup containing the elements you want to lose focus off.
*/
void addTouchListener(ArrayList<Integer> excludedResIds, ViewGroup parent)
{
for(int index = 0; index<parent.getChildCount(); ++index) {
View nextChild = parent.getChildAt(index);
try{
addTouchListener(excludedResIds, (ViewGroup) nextChild);
}catch (Exception e){
}
if(!excludedResIds.contains(nextChild.getId()))
nextChild.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
constraintLayout.requestFocus();
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
return false;
}
});
}
}
}

android.view.InflateException: Binary XML file line #7: Error inflating class fragment

I know similar questions like this has been answered but I seem to have done what the tutorial suggested and reading from other posts but still I get the Inflator error. Not sure what I am doing wrong. Please check the code. Thanks a lot.
Edit: I have two fragments in an activity. I have a button in one fragment and a textview in the other. I am trying to understand how fragments work so I made this code myself after reading the documentation. When the button is triggered in one fragment it sends a value to the other fragment in the activity. I am not able to get the fragment to inflate
MainActivity.java
import com.transport.mbtalocpro.PredictedTimeFragment.ButtonClickListener;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity implements ButtonClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void sendCounter(int count) {
TestFrag testF = (TestFrag) getSupportFragmentManager().findFragmentById(R.id.bottomHalf);
if(testF != null) testF.setCounter(String.valueOf(count));
}
}
PredictedTimeFragment.java
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
public class PredictedTimeFragment extends Fragment {
ButtonClickListener bListener;
public interface ButtonClickListener {
public void sendCounter(int count);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
try {
View view = inflater.inflate(R.layout.prediction_time, container, false);
Button button = (Button) view.findViewById(R.id.test);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
test(v);
}
});
} catch(InflateException e) {
e.printStackTrace();
System.out.println("Predicted Time Fragment");
}
return super.onCreateView(inflater, container, savedInstanceState);
}
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
bListener = (ButtonClickListener) activity;
} catch (ClassCastException e) {
System.out.println("must implemenet Listener");
}
}
public void test(View view) {
bListener.sendCounter(23);
}
}
TestFrag.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class TestFrag extends Fragment {
#Override
public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflator, container, savedInstanceState);
try {
View view = inflator.inflate(R.layout.test_frag, container, false);
} catch(InflateException e) {
e.printStackTrace();
System.out.println("Test Fragment");
}
return super.onCreateView(inflator, container, savedInstanceState);
}
public void setCounter(String textS) {
TextView text = (TextView) getView().findViewById(R.id.test1);
text.setText((String) textS);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical">
<fragment
android:id="#+id/topHalf"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:name="com.transport.mbtalocpro.PredictedTimeFragment"/>
<fragment
android:id="#+id/bottomHalf"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:name ="com.transport.mbtalocpro.TestFrag"/>
</LinearLayout>
predicted_time.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" >
<Button
android:id="#+id/test"
android:text="Test"
android:layout_width="fill_parent"
android:layout_height="30dp"
/>
</LinearLayout>
test_frag.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" >
<TextView
android:id="#+id/test1"
android:layout_width="fill_parent"
android:layout_height="40dp"/>
</LinearLayout>
I am trying to support pre-honey comb versions too and I think I am importing all the support libraries.
Delete your import statement:
import android.support.v4.app.FragmentActivity;
And import again with the pop-up import suggestion. I donĀ“t know why but it always works for me.
import android.support.v4.app.FragmentActivity;
To fix the error:
In Manifest:
<application
android:largeHeap="true"
In .xml file, you must remove the below code:
android:src="#drawable..
android:background="#drawable...
Because the error is out of memory error
In the onCreateView callbacks you have to return the view, which you inflated. This way the system knows which View to draw. Otherwise, if you just return super.onCreateView(...); this way, no UI will appear.
Try this:
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
try {
View view = inflater.inflate(R.layout.prediction_time, container, false);
Button button = (Button) view.findViewById(R.id.test);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
test(v);
}
});
} catch(InflateException e) {
e.printStackTrace();
System.out.println("Predicted Time Fragment");
}
return view;
}
Change the return value of the other Fragment accordingly.
Try replacing the fragment in your xml with android.support.v4.app.Fragment
EDIT: Also try to call super when you are done with your views in onCreateView i.e only once. remove the call to the super in the beginning and see if that helps
change your layout widget id ,it works for me.

android: setOnKeyListener issue with fragments

UPDATED ItemEntryFragment.java and ToDoActivity.java to include my latest attempt to get this thing to work, but it doesn't
I am in an android development class. our assignment is to make a simple todo list using two fragments. The first fragment is an EditText and the second is a listView.
when a user enters an item into the edittext box and hits enter, the string is added to the listview.
update 2 The application now successfully loads on my phone and the fragments look as expected. however when I press the enter key after inputting text in the EditText line, the setOnKeyListener is never fired. The code segments are the most current.
any suggestions/pointers would be appreciated.
Below are my xml files that I think are correct
main.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" >
<fragment
android:name="com.todo.ToDoListFragment"
android:id="#+id/todolistFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<fragment
android:name="com.todo.ItemEntryFragment"
android:id="#+id/textboxFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
_
list_view_fragment.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" >
<EditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#string/addItemContentDescription"
android:hint="#string/addItemHint" />
</LinearLayout>
_
edit_text_fragment.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" >
</LinearLayout>
and here are my .java files
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
public class ItemEntryFragment extends Fragment{
private ToDoListActivity activity;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.text_entry_box, container, false);
final EditText myEditText = (EditText)view.findViewById(R.id.myEditText);
myEditText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN)
if((keyCode == KeyEvent.KEYCODE_DPAD_CENTER) || (keyCode == KeyEvent.KEYCODE_ENTER)) {
String newItem = myEditText.getText().toString();
activity.addItem(newItem);
myEditText.setText("");
return true;
}
return false;
}
});
return view;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.activity = (ToDoListActivity)activity;
}
}
_
public class ToDoListFragment extends ListFragment {
//this class is empty because the ListFragment auto adds the ListView
}
and here is my main java file
import java.util.ArrayList;
import android.app.Activity;
import android.app.FragmentManager;
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class ToDoListActivity extends Activity {
private ArrayAdapter<String> aa;
private ArrayList<String> todoItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//inflate view
setContentView(R.layout.activity_to_do_list);
//get references to fragments
FragmentManager fm = getFragmentManager();
ToDoListFragment todoListFragment = (ToDoListFragment) fm.findFragmentById(R.id.todolistFragment);
todoItems = new ArrayList<String>();
//create array adaptor to bind array to list view
aa = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems);
//bind array adapter to list view
todoListFragment.setListAdapter(aa);
}
public void addItem(String newItem){
todoItems.add(newItem);
aa.notifyDataSetChanged();
}
}
Maybe try to hook into onEditorAction and set the EditText properties as mentioned here

Categories

Resources