質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

0回答

1062閲覧

React NativeでAndroidでもリストをD&Dで並べ替えできるようにしたいです。

nananananally

総合スコア1

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2020/10/13 00:48

iOSとAndroidで動作する写真投稿機能を持つアプリを開発しています。
いろいろ調べましたが、どうにも解決できなかったので相談させてください。

困っていること

  • Androidで、並び替え可能なフラットリストが機能しない。(あるコンポーネント内では動作するのに、他のコンポーネント内では動作しない)
  • iOSでは正常に動作している

スクリーンショット

  • 正常に並び替えができる箇所

イメージ説明

  • 並び替えができない箇所

イメージ説明

並び替えに使用しているmodule

react-native-cli: 2.0.1 react-native: 0.63.1 react-native-draggable-flatlist: 2.4.0 (https://github.com/computerjazz/react-native-draggable-flatlist)

コードと説明

  • 写真投稿画面で「画像を選択する」をクリックすると、画像選択用のモーダルが出現。
  • 投稿する画像を選択すると、画面下部に選択した画像のサムネイルが表示される。(スクリーンショット2枚目)
  • それらは並び替え可能なリストだが、Androidでは並び替えできない(onLongPressは発火してる)
  • 画像選択完了後、スクリーンショット1枚目の画面では、正常に並び替えができる

Javascript

1【styleや無関係なメソッドなどは削除して記載してあります】 2 3 4/** 5 * Component1: 「画像を選択する」ボタンが設置されているコンポーネント 6 * このコンポーネント直下でレンダリングされた<PreviewArea>では普通にドラッグアンドドロップの並び替えが機能します 7 */ 8export class FileSelectArea extends Component { 9 constructor(props) { 10 super(props); 11 this.state = { 12 selectedImages: [], 13 showModal: false, 14 } 15 this.setSelectedImages = this.setSelectedImages.bind(this); 16 this.toggleModal = this.toggleModal.bind(this); 17 } 18 19 static contextType = Context; 20 21 setSelectedImages(selectedImages) { 22 this.setState({ 23 selectedImages: selectedImages, 24 }); 25 } 26 27 toggleModal() { 28 this.setState({ 29 showModal: !this.state.showModal, 30 }); 31 } 32 33 render() { 34 return ( 35 <PhotoRegisterContext.Provider 36 value={{ 37 selectedImages: this.state.selectedImages, 38 setSelectedImages: this.setSelectedImages, 39 }} 40 > 41 <TouchableOpacity 42 onPress={() => this.toggleModal()} 43 > 44 <Text>画像を選択する</Text> // ←(1)クリックするとモーダルが出現 45 </TouchableOpacity> 46 47 {this.state.selectedImages.length > 0 && 48 <View> 49 <PreviewArea 50 viewType="registerPage" 51 /> // ←(2)正常に動作する並び替えエリア 52 </View> 53 } 54 55 <Modal 56 animationType="card" 57 visible={this.state.showModal} 58 > // ←(3)モーダルが表示され、モーダル内で画像の選択や写真の撮影が可能 59 <PhotoSelectModalTabNavigator 60 toggleModal={this.toggleModal} 61 /> 62 </Modal> 63 </PhotoRegisterContext.Provider> 64 ); 65 }; 66} 67 68/** 69 * Component2: タブナビゲーター 70 */ 71const Tab = createBottomTabNavigator(); 72const PhotoSelectModalTabNavigator = (props) => { 73 return ( 74 <Tab.Navigator 75 tabBar={(props) => <ModalFooter {...props} />} // ←(4)モーダル内のtabNavigator上に、(2)と同様のPreviewAreaコンポーネントが設置されている 76 > 77 <Tab.Screen name="Album"> 78 {(props) => <CameraRollPickerArea {...props} />} 79 </Tab.Screen> 80 <Tab.Screen name="Camera"> 81 {(props) => <CameraArea {...props} />} 82 </Tab.Screen> 83 </Tab.Navigator> 84 ); 85} 86 87/** 88 * Component3: 並び替え可能なFlatListコンポーネント 89 */ 90class PreviewArea extends Component { 91 constructor(props) { 92 super(props); 93 this.state = { 94 showPreviewImageModal: false, 95 previewImageIndex: 1, 96 }; 97 this.setShowStatus = this.setShowStatus.bind(this); 98 this.handlePressIconDelete = this.handlePressIconDelete.bind(this); 99 } 100 101 static contextType = PhotoRegisterContext; 102 103 setShowStatus(status) { 104 this.setState({ 105 showPreviewImageModal: status, 106 }); 107 } 108 109 handlePressIconDelete(targetIndex) { 110 const selectedImages = this.context.selectedImages; 111 112 const newSelectedImages = selectedImages.filter((item, index) => { 113 return index != targetIndex; 114 }); 115 116 this.context.setSelectedImages(newSelectedImages); 117 } 118 119 handlePressThumbnail(uri) { 120 const images = []; 121 this.context.selectedImages.map(item => images.push(item.uri)); 122 123 this.setState({ 124 showPreviewImageModal: true, 125 previewImageIndex: images.indexOf(uri), 126 }); 127 } 128 129 renderItem = ({ item, index, drag, isActive }) => { 130 return ( 131 <View> 132 <TouchableWithoutFeedback 133 onLongPress={(e) => { 134 drag(); 135 }} 136 onPress={() => this.handlePressThumbnail(item.uri)} 137 > 138 <Image 139 resizeMode="contain" 140 source={{ 141 uri: item.uri, 142 }} 143 /> 144 </TouchableWithoutFeedback> 145 </View> 146 ); 147 }; 148 149 150 render() { 151 const images = []; 152 this.context.selectedImages.map(item => images.push({url: item.uri})); 153 154 return ( 155 <DraggableFlatList 156 horizontal 157 renderPlaceholder={({item}) => ( 158 <Image 159 resizeMode="contain" 160 source={{uri: item.uri}} 161 /> 162 )} 163 keyExtractor={(item) => this.props.viewType === 'selectImageModal'? `inSelectImageModal${item.uri}`: `inRegisterPage${item.uri}`} 164 data={this.context.selectedImages} 165 renderItem={this.renderItem} 166 onDragEnd={({data}) => { 167 this.context.setSelectedImages(data); 168 }} 169 /> 170 ) 171 } 172} 173 174/** 175 * Component4: モーダル内のフッターエリア 176 */ 177class ModalFooter extends Component { 178 constructor(props) { 179 super(props); 180 this.state = {}; 181 } 182 183 static contextType = PhotoRegisterContext; 184 185 render () { 186 const {state, descriptors, navigation} = this.props; 187 188 return ( 189 <View> 190 <View 191 style={styles.selectModalPreviewArea} 192 > 193 <PreviewArea 194 viewType="selectImageModal" 195 /> // ←(5)ドラッグアンドドロップによる並び替えが動作しない(Androidのみ)コンポーネント自体は(2)と共通 196 </View> 197 </View> 198 ); 199 } 200} 201

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問