2017-05-24 9 views
0

코드에서 팝업 창을 표시하여 화면에서 터치 한 위치에 상관없이 내가 터치 한 위치 바로 위에 팝업이 나타나야합니다. . 확실하지 않은, 이것을 달성하는 방법. 이것은 내 popup.xml입니다화면에서 건 드린 장소 바로 위에 팝업 창을 표시하려면 어떻게합니까?

LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); 

          View customView = inflater.inflate(R.layout.popup,null); 

          final PopupWindow popupWindow = new PopupWindow(
            customView, 
            LayoutParams.WRAP_CONTENT, 
            LayoutParams.WRAP_CONTENT); 

          // Set an elevation value for popup window 
          // Call requires API level 21 
          if(Build.VERSION.SDK_INT>=21){ 
           popupWindow.setElevation(5.0f); 
          } 
          final TextView placename = (TextView) customView.findViewById(R.id.popup_id) ; 
          Button closeButton = (Button) customView.findViewById(R.id.directions); 
          placename.setText(place.getName()); 
          popupWindow.setBackgroundDrawable(new BitmapDrawable()); 
          popupWindow.setOutsideTouchable(true); 
          // Set a click listener for the popup window close button 
          closeButton.setOnClickListener(new View.OnClickListener() { 
           @Override 
           public void onClick(View view) { 
            // Dismiss the popup window 

            popupWindow.dismiss(); 

           } 
          }); 
          popupWindow.setFocusable(true); 

          popupWindow.showAtLocation(mapInsideContainer, Gravity.CENTER, 0, 0); 
          popupWindow.showAsDropDown(customView); 

: 이것은 내 현재 팝업 창 코드

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" 
    android:background="@android:color/background_light"> 
    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" 
     android:layout_margin="1dp" 
     android:background="@android:color/white"> 
     > 
     <LinearLayout 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:orientation="vertical" 
      android:layout_margin="20dp"> 
      <TextView 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:textColor="#000000" 
       android:id="@+id/popup_id" /> 
      <Button 
       android:id="@+id/directions" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:background="@color/black_overlay" 
       android:textColor="@android:color/white" 
       android:text="Directions" /> 
     </LinearLayout> 
    </LinearLayout> 
</LinearLayout> 

는 현재이 때문에 Gravity.CENTER로 화면 중앙에 표시됩니다,하지만 난 보여 드리고자합니다 내가 화면에서 동적으로 터치하는 곳 바로 위. 어떤 아이디어? 덕분에 당신은 위치에 거품 포인터 하단에 상단에 제목과 "장소"버튼을 팝업과 같은 채팅 거품을 만드는 과정 나를 인도 할 수

보너스 포인트 경우 PopupWindow를 사용하는

답변

0

대신 화면에 클릭 this과 유사한 투명한 활동을 만들어보십시오.

그런 다음 버블 포인터가 사용자가 클릭 한 위치에 따라 다른 위치에 있어야하므로 채팅 거품에 대한 사용자 정의 드로어 블을 만들 수 있습니다. onTouchEvent()를 재정 의하여 사용자 터치 좌표를 가져온 다음 투명 액티비티를 실행하고 인 텐트의 좌표를 전달하여 적절한 지점에 버블 뷰를 배치 할 수 있습니다.

새로운 활동을 시작하기 때문에 추가 오버 헤드가 발생하지만 원하는대로 모양과 동작을 사용자 정의 할 수 있습니다.

여기에 몇 가지 세부 사항이 있습니다. 이것은 사용자 정의 된 팝업 메뉴를 원할 때 내가 한 것입니다.

투명 활동을 위해, 새로운 활동을 생성하고 매니페스트에에 테마를 지정 :

<activity 
     android:name=".PopupActivity" 
     android:theme="@style/Transparent" /> 

그리고 styles.xml에서

:

<style name="Transparent" parent="Theme.AppCompat.NoActionBar"> 
    <item name="android:windowIsTranslucent">true</item> 
    <item name="android:windowBackground">@color/translucent</item> 
</style> 

당신은 완전히로 @color/translucent를 정의 할 수 있습니다 투명, 팝업을 표시 할 때 아래에보기를 희미하게 보이게하려면 회색을 추가하십시오. 활동에 대한 레이아웃에서

:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_popup" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@color/colorPrimary" 
    android:layout_margin="60dp"> 
여기

내가 RelativeLayout의를 사용하고 있습니다,하지만 당신은 당신이 원하는대로 레이아웃을 사용할 수는, 중요한 것은 여백입니다. 배경 활동이 하나의 뒤에 표시입니다 이제 활동은 다음과 같습니다

다음 당신은 당신이 원하는 목적지 직사각형을 표시하기 위해 터치가 동적으로 여백을 변경하는 좌표를 사용합니다.

우리는 당신의 주요 활동에서 onCreate() 메소드에 있으므로, 추가, 화면 크기와 밀도, 화면 상단의 상태 표시 줄의 높이를 알아야합니다 :

//Determine the screen dimensions and density 
DisplayMetrics metrics = new DisplayMetrics(); 
getWindowManager().getDefaultDisplay().getMetrics(metrics); 
screenWidth = metrics.widthPixels; 
screenHeight = metrics.heightPixels; 
screenDensity = metrics.density; 
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); 
int statusBarHeight = (int) (24 * density); 
if (resourceId > 0) { 
    statusBarHeight = getResources().getDimensionPixelSize(resourceId); 
} 

이 값은 변경되지 않으므로 다른 클래스가 필요할 때 정적 변수에 저장할 수 있습니다.투명 활동에서 onCreate() 메소드에서 지금

, 터치 이벤트에 기초하여 상기 마진을 계산 좌표 :

int popupSize = 100; 
int rMargin, lMargin, tMargin, bMargin; 

lMargin = xCoord - popupSize; 
rMargin = screenWidth - xCoord - popupSize; 
tMargin = yCoord - popupSize; 
bMargin = screenHeight - yCoord - popupSize - statusBarHeight; 

RelativeLayout layout = (RelativeLayout) findViewById(R.id.activity_popup); 
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) layout.getLayoutParams(); 
params.setMargins(lMargin, tMargin, rMargin, bMargin); 
layout.setLayoutParams(params); 

이 터치 좌표 중심 사각형을 생성한다.

enter image description here

을 그리고 X = 150, Y = 200, I 얻을 : 예를 들어, X = 700, Y = 1500을 주어, 나는 얻을

enter image description here

당신은 것을 볼 수 있습니다 이 경우 좌표가 가장자리에 너무 가까우면 음수 여백이 생기고 사각형이 잘립니다. 이 문제를 해결하려면 더 많은 수학이 필요합니다.

화면 영역을 네 사분면으로 나누고 터치 이벤트가있는 사분면을 계산하는 것입니다. 그런 다음 터치가 왼쪽 위 사분면에있는 경우 사각형의 왼쪽 위 모서리를 터치 좌표. 이렇게하면 사각형이 화면 가장자리에서 잘리지 않습니다.

포인터가 달린 거품을 만드는 경우, 각기 다른 꼭지점에 포인터가있는 거품의 사용자 정의 드로어 블을 4 개 만듭니다. 그런 다음 터치 이벤트의 사분면에 따라 포인터가 항상 올바른 방향이되도록 적절한 드로어 블을로드하십시오.

이 게시물은 약간 길어지고 있습니다.

+0

당신은 부분이 혼란 투명 활동으로 도움이 될 것입니다 자세한 도움을 줄 수 그리고 난 그 팝업 창이 바로 표시하지 않는 문제를 해결 얼마나 아무 생각이없는 경우 터치 포인트 위 –

+0

@ JusticeBauer 나는 몇 가지 세부 사항을 제공하기 위해 나의 대답을 편집했다. 오늘 밤 더 편집 하겠지만 지금 가야합니다. –

+0

@ JusticeBauer 더 자세한 내용을 추가했습니다. –

0
이 내가 무슨 짓을

, 당신이

customView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 

popupWindow.showAtLocation(getWindow().getDecorView(), Gravity.NO_GRAVITY, (int)event.getX(), (int)event.getY() - customView.getMeasuredHeight()); 

그리고 public boolean onTouchEvent(MotionEvent event)

@Override 
    public boolean onTouchEvent(MotionEvent event) { 
     popup(event); 
     return super.onTouchEvent(event); 
    } 

편집을 무시 희망 도움말 : 다음과 같이 내 쓰기, 그리고 그것은 나를 위해 일합니다.

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     popup(event); 
     return super.onTouchEvent(event); 
    } 

    private void popup(MotionEvent event) { 
     LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); 

     View customView = inflater.inflate(R.layout.popup,null); 

     final PopupWindow popupWindow = new PopupWindow(
       customView, 
       WindowManager.LayoutParams.WRAP_CONTENT, 
       WindowManager.LayoutParams.WRAP_CONTENT); 

     // Set an elevation value for popup window 
     // Call requires API level 21 
     if(Build.VERSION.SDK_INT>=21){ 
      popupWindow.setElevation(5.0f); 
     } 
     final TextView placename = (TextView) customView.findViewById(R.id.popup_id) ; 
     Button closeButton = (Button) customView.findViewById(R.id.directions); 
     placename.setText("Name"); 
     popupWindow.setBackgroundDrawable(new BitmapDrawable()); 
     popupWindow.setOutsideTouchable(true); 
     // Set a click listener for the popup window close button 
     closeButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       // Dismiss the popup window 

       popupWindow.dismiss(); 

      } 
     }); 
//  popupWindow.setFocusable(true); 
     popupWindow.setOutsideTouchable(true); 
     customView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 
     popupWindow.showAtLocation(getWindow().getDecorView(), Gravity.NO_GRAVITY, (int)event.getX(), (int)event.getY() - customView.getMeasuredHeight()); 

     getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       return false; 
      } 
     }); 
    } 

} 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/parent" 
    android:background="@color/colorAccent" 
    android:fitsSystemWindows="true"> 


</android.support.constraint.ConstraintLayout> 
+0

(int) event.getY() and (int) event.getX(), whats event 여기에? 그것은 오류로 나타나고있다 –

+0

내가 실제로 원하는 것을 알지 못한다. 팝업 창을 보여주기 위해 그것을 터치한다. 그래서'public boolean onTouchEvent (MotionEvent event)'액티비티를 오버라이드한다. 그래서 param 이벤트는 다음과 같다. 이벤트가'(int) event.getX()'에 있다면, 당신의 타겟 뷰가'mapInsideContainer'이면,'public void setOnTouchListener (OnTouchListener l)'을 사용할 수 있습니다. – VictorPanda

+0

도 작동하지 않습니다. 계산하기가 더 쉬워 –