Creating Android overlays for displaying Walk-through - android

This is what I've done to implement CommonsWare's answer in the following question:
How do I create a help overlay like you see in a few Android apps and ICS?
But it fails. There are no errors but nothing appears when I run (I've made sure that the isFirstTime() function below is functioning properly
#Override
public void onCreate(Bundle savedInstanceState)
{
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
if(isFirstTime())
{
LayoutInflater inflater = LayoutInflater.from(this);
final FrameLayout overlayFrameLayout = new FrameLayout(this);
setContentView(overlayFrameLayout);
overlayFrameLayout.addView(inflater.inflate(R.layout.main, null));
overlayFrameLayout.addView(inflater.inflate(R.layout.overlay, null));
overlayFrameLayout.setVisibility(View.VISIBLE);
overlayFrameLayout.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
overlayFrameLayout.setVisibility(View.INVISIBLE);
overlayFrameLayout.removeViewAt(1);
return false;
}
});
}
setContentView(R.layout.main);
ctx = getApplicationContext();
I'm pretty sure that I've gone wrong when creating the FrameLayout. Appreciate the help, thanks!

You don't see anything because you call setContentView twice and the R.layout.main is being inflated and replacing your previously created and assigned overlayFrameLayout. The following code should sort it out.
#Override
protected void onCreate(Bundle savedInstanceState)
{
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
if(isFirstTime()){
final LayoutInflater inflater = getLayoutInflater();
final FrameLayout frameLayout = new FrameLayout(this);
inflater.inflate(R.layout.main, frameLayout, true);
final View overlayView = inflater.inflate(R.layout.overlay, frameLayout, false);
overlayView.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
frameLayout.removeView(overlayView);
return false;
}
});
frameLayout.addView(overlayView);
setContentView(frameLayout);
}
else{
setContentView(R.layout.main);
}
}

Related

Not able to create buttons dynamically

I have an overlay on my screen which will show some buttons to control the feature. This overlay will have a dynamic list of buttons which will be created based on the number of steps. Example if steps are 3 then 3 button will get created. I have created a LinearLayout inside this buttons will get created. I have created a method which will set all the button attributes, but somehow it's giving me null pointer exception.
In onCreateView I have initialize the buttonArray.
Here is my fragment:
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mContext = getActivity();
gc = GlobalClass.getInstance(mContext);
db = DataBaseHelper.getInstance(mContext);
sectionButtons = new Button[3];
/*if(savedInstanceState!=null)
mVisible = savedInstanceState.getBoolean("visible",false);*/
manager = SharedPreferenceManager.getInstance(mContext);
//check wether to play video in cover mode or another mode
inflater.inflate(R.layout.fragment_video_side_by_side, container, false);
}
and onViewCreated() I am calling my method addSections():
// show overlay with buttons in onTouch
parentLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (!mVisible) {
overLay.setVisibility(View.VISIBLE);
addSections(3);
mVisible = true;
} else {
overLay.setVisibility(View.GONE);
mVisible = false;
}
}
return true;
}
});
Method:
public void addSections(int numOfSection){
if(numOfSection==0)
return;
else {
for (int i = 0; i < numOfSection; i++) {
//set the properties for button
sectionButtons[i].setLayoutParams(new LinearLayout.LayoutParams(50, 50));
sectionButtons[i].setBackgroundResource(R.drawable.round_button);
sectionButtons[i].setText("Section "+i+"");
sectionButtons[i].setId(i);
//add button to the layout
mSectionLayout.addView(sectionButtons[i]);
}
}
}
mSectionLayout is my parent LinearLayout. While debugging I found my sectionButtons is not showing null but while setting the attributes it's throwing nullPointer exception.
Create Dynamic Buttons and attach with the Layout
You can easily create the dynamic button by the following way:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
TextView textView = new TextView(this);
textView.setText("Text View ");
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
layout.addView(textView, p);
Button buttonView = new Button(this);
buttonView.setText("Button");
buttonView.setOnClickListener(mThisButtonListener);
layout.addView(buttonView, p);
}
private OnClickListener mThisButtonListener = new OnClickListener() {
public void onClick(View v) {
Toast.makeText(MainActivity.this, "Hello !",
Toast.LENGTH_LONG).show();
}
};
}
Using this code, you easily generate a list of buttons on the layout.
Happy coding

Android: TextView Causes app to crash

I've got a TextView that crashes the app when trying to setText. I'm not using the XML layout and have set a custom view to handle everything. Obviously the app crashes when the screen is touched after the app is initalized.
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout lv = new LinearLayout(this);
lv.setOrientation(LinearLayout.VERTICAL);
mView = new MyView(this);
TextView tvX = new TextView(this);
lv.addView(tvX);
lv.addView(mView);
lv.setBackgroundColor(Color.GRAY);
tvX.setTextColor(Color.WHITE);
tvX.setText("Ahmad");
setContentView(lv);
mView.requestFocus();
public class MyView extends View {
private TextView tvX;
public void setTextView(TextView tv){
tvX = tv;
}
#Override public boolean onTouchEvent(MotionEvent event) {
tvX.setText("123");
}
Any help is appreciated!
EDIT 1
08-27 00:39:49.859: E/MessageQueue-JNI(510): at co.projx.touchpaint.TouchPaint$MyView.onTouchEvent(TouchPaint.java:286)
08-27 00:39:49.874: E/AndroidRuntime(510): at co.projx.touchpaint.TouchPaint$MyView.onTouchEvent(TouchPaint.java:286)
Your problem is the same as here: View becomes null on setText
You're missing the LayoutParams (WRAP_CONTENT, WRAP_CONTENT).

NULL Pointer Exception while implementing Touch Listener in Android

I am trying to create simple app through Drag and Touch Listeners. But when I am setting the TouchListener to the TextView Control through inner class, getting NullPointerException : Here is the code.
public class MainActivity extends Activity
{
private TextView option1, choice1;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
option1 = (TextView)findViewById(R.id.option_1);
setContentView(R.layout.activity_main);
option1.setOnTouchListener(new ChoiceTouchListener()); [NULLPOINTER]
}
private final class ChoiceTouchListener implements OnTouchListener
{
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
if(arg1.getAction() == MotionEvent.ACTION_DOWN)
{
ClipData clipdata = ClipData.newPlainText("","");
DragShadowBuilder shadowbuilder = new DragShadowBuilder(arg0);
arg0.startDrag(clipdata, shadowbuilder, arg0, 0);
return true;
}
else
{
return false;
}
}
}
}
Change:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
option1 = (TextView)findViewById(R.id.option_1);
setContentView(R.layout.activity_main);
option1.setOnTouchListener(new ChoiceTouchListener());
}
To
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
option1 = (TextView)findViewById(R.id.option_1);
option1.setOnTouchListener(new ChoiceTouchListener());
}
findViewById() looks for a View with the supplied ID in the currently inflated layout. However, you try to use findViewById() before calling setContentView(), which results in option1 getting a null value as there is no currently inflated layout. Reordering the statements should fix this

Existing classes are not working in new project with intents

I wrote an app with 1 activity and 1 view, so it gives me the coordinates of my fingers i put on the screen. Worked perfectly.
The Problem is now: I Created a new App with more than 1 Activity so i can change between them with intents. also worked fine. But one Activity should be the one wich give me my finger positions. So i Copyed the class and activity put them into the manifest. And made a Button and a intend for to run it.
So when i try to run it it creates the class but doesnt react on my onTouchEvents anymore...
and i have no clue why. i hope i explained my problem well enough for u guys to understand.
So this is my main activity. starts the menu with the option to go to the not working class
public class V1_2 extends Activity implements OnClickListener{
Button btn_1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_v1_2);
btn_1 = (Button) findViewById(R.id.button1);
btn_1.setOnClickListener(this);
}
public void onClick(View v) {
if( btn_1.getId() == ((Button)v).getId() ){
startActivity(new Intent(this,Obj_recog.class));
}
}
This is now the activity wich creates the touchpiont class for the touchevents
public class Obj_recog extends Activity implements OnClickListener{
touchtest TP;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blank);
TP = new touchtest(this);
}
public void onClick(View v) {
}
And now an example of what doesnt work here but worked at the last project the same way
public class touchtest extends View{
public touchtest(Context context) {
super(context);
Log.d("worked", "worked");
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
Log.d("Touch", "TOUCH!!!!");
return true;
}
}
So i get the message that it "worked" but it doesnt react on touchevents like it used to do...
It will be worked if you add touchtest view as your main view by using setcontentview and then
add touchlistener on that view and call your ontouchevent from your touchtest class. code will be like --
TP = new touchtest(this);
setContentView(TP);
TP.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
TP.onTouchEvent(event);
return false;
}
});
i think should change this approach find an alternative way to implement for which you are going in this way.
In this way you can keep your blank layout and also TP.
RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl);
TP = new touchtest(this);
rl.addView(TP);
TP.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
TP.onTouchEvent(event);
return false;
}
});

Persist views across screen rotation

New to Android so I'm writing small programs to get familiar with how things work.
What has been giving me a headache so far are views created at runtime in combination with screen rotation.
After having little luck trying to use parcels, I solved the problem by just recreating the views after a rotation.
The program will add the entered text as a TextView to a TableLayout below the EditText.
Is there a better way of solving this? I could not find any "out of the box" methods for doing this.
public class MWEActivity extends Activity {
TableLayout table;
EditText txtInput;
ArrayList<String> savedEntry = new ArrayList<String>();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
table = (TableLayout)this.findViewById(R.id.table);
txtInput = (EditText)this.findViewById(R.id.txtInput);
txtInput.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN){
TextView newtext = new TextView(getApplicationContext());
newtext.setText(txtInput.getText());
savedEntry.add(newtext.getText().toString());
table.addView(newtext);
txtInput.setText("");
return true;
}
return false;
}
});
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putStringArrayList("entry", savedEntry);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if(savedInstanceState.getStringArrayList("entry") == null){
savedEntry = new ArrayList<String>();
savedEntry.add("Return was NULL");
}else{
savedEntry = savedInstanceState.getStringArrayList("entry");
}
for(String s : savedEntry){
TextView tv = new TextView(getApplicationContext());
tv.setText(s);
table.addView(tv);
}
super.onRestoreInstanceState(savedInstanceState);
}
}
Either you have to disable orientation change like in previous answer, or just rely
on standard facility. It will pause an then recreate your activity. No extra code is necessary. You can also provide different layouts for different orientations:
http://developer.android.com/guide/practices/screens_support.html
You can stop the reloading of the activity by putting
android:configChanges="orientation"
in the manifest.xml for the activity and implementing onConfigurationChanged.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
If your layout is the same you should not need to do anything else.

Categories

Resources